/*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
OFPROTO_FOR_EACH_TABLE (table, &ofproto->up) {
struct cls_cursor cursor;
- ovs_rwlock_rdlock(&table->cls.rwlock);
+ fat_rwlock_rdlock(&table->cls.rwlock);
cls_cursor_init(&cursor, &table->cls, NULL);
- ovs_rwlock_unlock(&table->cls.rwlock);
+ fat_rwlock_unlock(&table->cls.rwlock);
CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, up.cr, &cursor) {
ofproto_rule_delete(&ofproto->up, &rule->up);
}
if (wc) {
memset(&wc->masks.dl_type, 0xff, sizeof wc->masks.dl_type);
- wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
+ if (is_ip_any(flow)) {
+ wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
+ }
}
cls = &ofproto->up.tables[table_id].cls;
- ovs_rwlock_rdlock(&cls->rwlock);
+ fat_rwlock_rdlock(&cls->rwlock);
frag = (flow->nw_frag & FLOW_NW_FRAG_ANY) != 0;
if (frag && ofproto->up.frag_handling == OFPC_FRAG_NORMAL) {
/* We must pretend that transport ports are unavailable. */
*rule = rule_dpif_cast(rule_from_cls_rule(cls_rule));
rule_dpif_ref(*rule);
- ovs_rwlock_unlock(&cls->rwlock);
+ fat_rwlock_unlock(&cls->rwlock);
return *rule != NULL;
}
struct xlate_out xout;
struct xlate_in xin;
struct flow flow;
+ struct flow_wildcards wc;
struct ds *result;
};
ds_put_char(result, '\n');
}
+static void
+trace_format_megaflow(struct ds *result, int level, const char *title,
+ struct trace_ctx *trace)
+{
+ struct match match;
+
+ ds_put_char_multiple(result, '\t', level);
+ ds_put_format(result, "%s: ", title);
+ flow_wildcards_or(&trace->wc, &trace->xout.wc, &trace->wc);
+ match_init(&match, &trace->flow, &trace->wc);
+ match_format(&match, result, OFP_DEFAULT_PRIORITY);
+ ds_put_char(result, '\n');
+}
+
static void
trace_resubmit(struct xlate_in *xin, struct rule_dpif *rule, int recurse)
{
trace_format_flow(result, recurse + 1, "Resubmitted flow", trace);
trace_format_regs(result, recurse + 1, "Resubmitted regs", trace);
trace_format_odp(result, recurse + 1, "Resubmitted odp", trace);
+ trace_format_megaflow(result, recurse + 1, "Resubmitted megaflow", trace);
trace_format_rule(result, recurse + 1, rule);
}
struct ds *ds)
{
struct rule_dpif *rule;
- struct flow_wildcards wc;
+ struct trace_ctx trace;
ds_put_format(ds, "Bridge: %s\n", ofproto->up.name);
ds_put_cstr(ds, "Flow: ");
flow_format(ds, flow);
ds_put_char(ds, '\n');
- flow_wildcards_init_catchall(&wc);
+ flow_wildcards_init_catchall(&trace.wc);
if (ofpacts) {
rule = NULL;
} else {
- rule_dpif_lookup(ofproto, flow, &wc, &rule);
+ rule_dpif_lookup(ofproto, flow, &trace.wc, &rule);
trace_format_rule(ds, 0, rule);
if (rule == ofproto->miss_rule) {
}
if (rule || ofpacts) {
- uint64_t odp_actions_stub[1024 / 8];
- struct ofpbuf odp_actions;
- struct trace_ctx trace;
- struct match match;
uint16_t tcp_flags;
tcp_flags = packet ? packet_get_tcp_flags(packet, flow) : 0;
trace.result = ds;
trace.flow = *flow;
- ofpbuf_use_stub(&odp_actions,
- odp_actions_stub, sizeof odp_actions_stub);
xlate_in_init(&trace.xin, ofproto, flow, rule, tcp_flags, packet);
if (ofpacts) {
trace.xin.ofpacts = ofpacts;
trace.xin.report_hook = trace_report;
xlate_actions(&trace.xin, &trace.xout);
- flow_wildcards_or(&trace.xout.wc, &trace.xout.wc, &wc);
ds_put_char(ds, '\n');
trace_format_flow(ds, 0, "Final flow", &trace);
-
- match_init(&match, &trace.flow, &trace.xout.wc);
- ds_put_cstr(ds, "Relevant fields: ");
- match_format(&match, ds, OFP_DEFAULT_PRIORITY);
- ds_put_char(ds, '\n');
+ trace_format_megaflow(ds, 0, "Megaflow", &trace);
ds_put_cstr(ds, "Datapath actions: ");
format_odp_actions(ds, trace.xout.odp_actions.data,