#include "unaligned.h"
#include "unixctl.h"
#include "vlog.h"
+#include "bundles.h"
VLOG_DEFINE_THIS_MODULE(ofproto);
ofproto->n_pending = 0;
hmap_init(&ofproto->deletions);
guarded_list_init(&ofproto->rule_executes);
- ofproto->n_add = ofproto->n_delete = ofproto->n_modify = 0;
- ofproto->first_op = ofproto->last_op = LLONG_MIN;
- ofproto->next_op_report = LLONG_MAX;
- ofproto->op_backoff = LLONG_MIN;
ofproto->vlan_bitmap = NULL;
ofproto->vlans_changed = false;
ofproto->min_mtu = INT_MAX;
OVS_NOT_REACHED();
}
- if (time_msec() >= p->next_op_report) {
- long long int ago = (time_msec() - p->first_op) / 1000;
- long long int interval = (p->last_op - p->first_op) / 1000;
- struct ds s;
-
- ds_init(&s);
- ds_put_format(&s, "%d flow_mods ",
- p->n_add + p->n_delete + p->n_modify);
- if (interval == ago) {
- ds_put_format(&s, "in the last %lld s", ago);
- } else if (interval) {
- ds_put_format(&s, "in the %lld s starting %lld s ago",
- interval, ago);
- } else {
- ds_put_format(&s, "%lld s ago", ago);
- }
-
- ds_put_cstr(&s, " (");
- if (p->n_add) {
- ds_put_format(&s, "%d adds, ", p->n_add);
- }
- if (p->n_delete) {
- ds_put_format(&s, "%d deletes, ", p->n_delete);
- }
- if (p->n_modify) {
- ds_put_format(&s, "%d modifications, ", p->n_modify);
- }
- s.length -= 2;
- ds_put_char(&s, ')');
-
- VLOG_INFO("%s: %s", p->name, ds_cstr(&s));
- ds_destroy(&s);
-
- p->n_add = p->n_delete = p->n_modify = 0;
- p->next_op_report = LLONG_MAX;
- }
-
return error;
}
if (fm->command == OFPFC_MODIFY_STRICT && fm->table_id != OFPTT_ALL
&& !(fm->flags & OFPUTIL_FF_RESET_COUNTS)) {
struct oftable *table = &ofproto->tables[fm->table_id];
- struct cls_rule match_rule;
struct rule *rule;
bool done = false;
- cls_rule_init(&match_rule, &fm->match, fm->priority);
fat_rwlock_rdlock(&table->cls.rwlock);
- rule = rule_from_cls_rule(classifier_find_rule_exactly(&table->cls,
- &match_rule));
+ rule = rule_from_cls_rule(classifier_find_match_exactly(&table->cls,
+ &fm->match,
+ fm->priority));
if (rule) {
/* Reading many of the rule fields and writing on 'modified'
* requires the rule->mutex. Also, rule->actions may change
return error;
}
- error = ofputil_decode_port_mod(oh, &pm);
+ error = ofputil_decode_port_mod(oh, &pm, false);
if (error) {
return error;
}
const struct ofp_header *request)
{
struct ofproto *p = ofconn_get_ofproto(ofconn);
- enum ofp_version version;
struct ofport *port;
struct list replies;
ofpmp_init(&replies, request);
-
- version = ofputil_protocol_to_ofp_version(ofconn_get_protocol(ofconn));
HMAP_FOR_EACH (port, hmap_node, &p->ports) {
- ofputil_append_port_desc_stats_reply(version, &port->pp, &replies);
+ ofputil_append_port_desc_stats_reply(&port->pp, &replies);
}
ofconn_send_replies(ofconn, &replies);
HMAP_FOR_EACH_WITH_HASH (op, hmap_node,
cls_rule_hash(cls_rule, table_id),
&ofproto->deletions) {
- if (cls_rule_equal(cls_rule, &op->rule->cr)) {
+ if (op->rule->table_id == table_id
+ && cls_rule_equal(cls_rule, &op->rule->cr)) {
return true;
}
}
uint64_t ofpacts_stub[1024 / 8];
struct ofpbuf ofpacts;
enum ofperr error;
- long long int now;
error = reject_slave_controller(ofconn);
if (error) {
goto exit_free_ofpacts;
}
- /* Record the operation for logging a summary report. */
- switch (fm.command) {
- case OFPFC_ADD:
- ofproto->n_add++;
- break;
-
- case OFPFC_MODIFY:
- case OFPFC_MODIFY_STRICT:
- ofproto->n_modify++;
- break;
-
- case OFPFC_DELETE:
- case OFPFC_DELETE_STRICT:
- ofproto->n_delete++;
- break;
- }
-
- now = time_msec();
- if (ofproto->next_op_report == LLONG_MAX) {
- ofproto->first_op = now;
- ofproto->next_op_report = MAX(now + 10 * 1000,
- ofproto->op_backoff);
- ofproto->op_backoff = ofproto->next_op_report + 60 * 1000;
- }
- ofproto->last_op = now;
+ ofconn_report_flow_mod(ofconn, fm.command);
exit_free_ofpacts:
ofpbuf_uninit(&ofpacts);
return table_mod(ofproto, &tm);
}
+static enum ofperr
+handle_bundle_control(struct ofconn *ofconn, const struct ofp_header *oh)
+{
+ enum ofperr error;
+ struct ofputil_bundle_ctrl_msg bctrl;
+ struct ofpbuf *buf;
+ struct ofputil_bundle_ctrl_msg reply;
+
+ error = ofputil_decode_bundle_ctrl(oh, &bctrl);
+ if (error) {
+ return error;
+ }
+ reply.flags = 0;
+ reply.bundle_id = bctrl.bundle_id;
+
+ switch (bctrl.type) {
+ case OFPBCT_OPEN_REQUEST:
+ error = ofp_bundle_open(ofconn, bctrl.bundle_id, bctrl.flags);
+ reply.type = OFPBCT_OPEN_REPLY;
+ break;
+ case OFPBCT_CLOSE_REQUEST:
+ error = ofp_bundle_close(ofconn, bctrl.bundle_id, bctrl.flags);
+ reply.type = OFPBCT_CLOSE_REPLY;;
+ break;
+ case OFPBCT_COMMIT_REQUEST:
+ error = ofp_bundle_commit(ofconn, bctrl.bundle_id, bctrl.flags);
+ reply.type = OFPBCT_COMMIT_REPLY;
+ break;
+ case OFPBCT_DISCARD_REQUEST:
+ error = ofp_bundle_discard(ofconn, bctrl.bundle_id);
+ reply.type = OFPBCT_DISCARD_REPLY;
+ break;
+
+ case OFPBCT_OPEN_REPLY:
+ case OFPBCT_CLOSE_REPLY:
+ case OFPBCT_COMMIT_REPLY:
+ case OFPBCT_DISCARD_REPLY:
+ return OFPERR_OFPBFC_BAD_TYPE;
+ break;
+ }
+
+ if (!error) {
+ buf = ofputil_encode_bundle_ctrl_reply(oh, &reply);
+ ofconn_send_reply(ofconn, buf);
+ }
+ return error;
+}
+
+
+static enum ofperr
+handle_bundle_add(struct ofconn *ofconn, const struct ofp_header *oh)
+{
+ enum ofperr error;
+ struct ofputil_bundle_add_msg badd;
+
+ error = ofputil_decode_bundle_add(oh, &badd);
+ if (error) {
+ return error;
+ }
+
+ return ofp_bundle_add_message(ofconn, &badd);
+}
+
static enum ofperr
handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
OVS_EXCLUDED(ofproto_mutex)
case OFPTYPE_QUEUE_GET_CONFIG_REQUEST:
return handle_queue_get_config_request(ofconn, oh);
+ case OFPTYPE_BUNDLE_CONTROL:
+ return handle_bundle_control(ofconn, oh);
+
+ case OFPTYPE_BUNDLE_ADD_MESSAGE:
+ return handle_bundle_add(ofconn, oh);
+
case OFPTYPE_HELLO:
case OFPTYPE_ERROR:
case OFPTYPE_FEATURES_REPLY: