From: Ben Pfaff Date: Mon, 15 Sep 2008 22:43:44 +0000 (-0700) Subject: Merge commit 'origin/master' X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7d8bab74dc293132fcb7fdd72ba497ca71d72ab;p=openvswitch Merge commit 'origin/master' Conflicts: switch/datapath.c utilities/dpctl.c --- b7d8bab74dc293132fcb7fdd72ba497ca71d72ab diff --cc switch/datapath.c index 0e715f17,24617efb..e5a2440f --- a/switch/datapath.c +++ b/switch/datapath.c @@@ -812,8 -809,8 +812,8 @@@ fill_flow_stats(struct ofpbuf *buffer, int table_idx, time_t now) { struct ofp_flow_stats *ofs; - int length = sizeof *ofs + sizeof *ofs->actions * flow->n_actions; + int length = sizeof *ofs + sizeof *ofs->actions * flow->sf_acts->n_actions; - ofs = buffer_put_uninit(buffer, length); + ofs = ofpbuf_put_uninit(buffer, length); ofs->length = htons(length); ofs->table_id = table_idx; ofs->pad = 0; @@@ -1215,6 -1214,55 +1217,55 @@@ error return error; } + static int + mod_flow(struct datapath *dp, const struct ofp_flow_mod *ofm) + { + int error = -ENOMEM; + int n_actions; + int i; + struct sw_flow_key key; + + + /* To prevent loops, make sure there's no action to send to the + * OFP_TABLE virtual port. + */ + n_actions = (ntohs(ofm->header.length) - sizeof *ofm) + / sizeof *ofm->actions; + for (i=0; iactions[i]; + + if (a->type == htons(OFPAT_OUTPUT) + && (a->arg.output.port == htons(OFPP_TABLE) + || a->arg.output.port == htons(OFPP_NONE) + || a->arg.output.port == ofm->match.in_port)) { + /* xxx Send fancy new error message? */ + goto error; + } + } + + flow_extract_match(&key, &ofm->match); + chain_modify(dp->chain, &key, ofm->actions, n_actions); + + if (ntohl(ofm->buffer_id) != UINT32_MAX) { - struct buffer *buffer = retrieve_buffer(ntohl(ofm->buffer_id)); ++ struct ofpbuf *buffer = retrieve_buffer(ntohl(ofm->buffer_id)); + if (buffer) { + struct sw_flow_key skb_key; + uint16_t in_port = ntohs(ofm->match.in_port); + flow_extract(buffer, in_port, &skb_key.flow); + execute_actions(dp, buffer, in_port, &skb_key, + ofm->actions, n_actions, false); + } else { + error = -ESRCH; + } + } + return error; + + error: + if (ntohl(ofm->buffer_id) != (uint32_t) -1) + discard_buffer(ntohl(ofm->buffer_id)); + return error; + } + static int recv_flow(struct datapath *dp, const struct sender *sender UNUSED, const void *msg) diff --cc utilities/dpctl.c index 1d9897d7,bd89065d..eef55a4d --- a/utilities/dpctl.c +++ b/utilities/dpctl.c @@@ -815,9 -812,10 +814,10 @@@ static void do_add_flow(int argc, char ofm->priority = htons(priority); ofm->reserved = htonl(0); - /* xxx Should we use the buffer library? */ + /* xxx Should we use the ofpbuf library? */ buffer->size -= (MAX_ADD_ACTS - n_actions) * sizeof ofm->actions[0]; + open_vconn(argv[1], &vconn); send_openflow_buffer(vconn, buffer); vconn_close(vconn); } @@@ -876,13 -873,40 +875,40 @@@ static void do_add_flows(int argc, cha fclose(file); } - static void do_del_flows(int argc, char *argv[]) + static void do_mod_flows(int argc, char *argv[]) { + uint16_t idle_timeout, hard_timeout; struct vconn *vconn; - uint16_t priority; - struct buffer *buffer; ++ struct ofpbuf *buffer; + struct ofp_flow_mod *ofm; + size_t size; + int n_actions = MAX_ADD_ACTS; + + /* Parse and send. */ + size = sizeof *ofm + (sizeof ofm->actions[0] * MAX_ADD_ACTS); + ofm = make_openflow(size, OFPT_FLOW_MOD, &buffer); + str_to_flow(argv[2], &ofm->match, &ofm->actions[0], &n_actions, + NULL, NULL, &idle_timeout, &hard_timeout); + ofm->command = htons(OFPFC_MODIFY); + ofm->idle_timeout = htons(idle_timeout); + ofm->hard_timeout = htons(hard_timeout); + ofm->buffer_id = htonl(UINT32_MAX); + ofm->priority = htons(0); + ofm->reserved = htonl(0); + + /* xxx Should we use the buffer library? */ + buffer->size -= (MAX_ADD_ACTS - n_actions) * sizeof ofm->actions[0]; open_vconn(argv[1], &vconn); + send_openflow_buffer(vconn, buffer); + vconn_close(vconn); + } + + static void do_del_flows(int argc, char *argv[]) + { + struct vconn *vconn; + uint16_t priority; - struct buffer *buffer; + struct ofpbuf *buffer; struct ofp_flow_mod *ofm; size_t size;