for (i = 0; i < chain->n_tables; i++) {
struct sw_table *t = chain->tables[i];
struct sw_flow *flow = t->lookup(t, key);
+ t->n_lookup++;
if (flow) {
t->n_matched++;
return flow;
memset(ots->pad, 0, sizeof ots->pad);
ots->max_entries = htonl(stats.max_flows);
ots->active_count = htonl(stats.n_flows);
+ ots->lookup_count = cpu_to_be64(stats.n_lookup);
ots->matched_count = cpu_to_be64(stats.n_matched);
}
return 0;
stats->wildcards = 0; /* No wildcards are supported. */
stats->n_flows = th->n_flows;
stats->max_flows = th->bucket_mask + 1;
+ stats->n_lookup = swt->n_lookup;
stats->n_matched = swt->n_matched;
}
stats->wildcards = 0; /* No wildcards are supported. */
stats->n_flows = substats[0].n_flows + substats[1].n_flows;
stats->max_flows = substats[0].max_flows + substats[1].max_flows;
+ stats->n_lookup = swt->n_lookup;
stats->n_matched = swt->n_matched;
}
stats->wildcards = OFPFW_ALL;
stats->n_flows = tl->n_flows;
stats->max_flows = tl->max_flows;
+ stats->n_lookup = swt->n_lookup;
stats->n_matched = swt->n_matched;
}
supported by the table. */
unsigned int n_flows; /* Number of active flows. */
unsigned int max_flows; /* Flow capacity. */
+ unsigned long int n_lookup; /* Number of packets looked up. */
unsigned long int n_matched; /* Number of packets that have hit. */
};
* rcu_read_lock. destroy must be fully serialized.
*/
struct sw_table {
- /* Keep track of the number of packets that matched this table. To
- * make this 100% accurate, it should be atomic. However, we're
- * primarily concerned about speed. */
- unsigned long int n_matched;
+ /* The number of packets that have been looked up and matched,
+ * respecitvely. To make these 100% accurate, they should be atomic.
+ * However, we're primarily concerned about speed. */
+ unsigned long long n_lookup;
+ unsigned long long n_matched;
/* Searches 'table' for a flow matching 'key', which must not have any
* wildcard fields. Returns the flow if successful, a null pointer
/* The most significant bit being set in the version field indicates an
* experimental OpenFlow version.
*/
-#define OFP_VERSION 0x91
+#define OFP_VERSION 0x92
#define OFP_MAX_TABLE_NAME_LEN 32
#define OFP_MAX_PORT_NAME_LEN 16
supported by the table. */
uint32_t max_entries; /* Max number of entries supported */
uint32_t active_count; /* Number of active entries */
+ uint64_t lookup_count; /* Number of packets looked up in table */
uint64_t matched_count; /* Number of packets that hit table */
};
-OFP_ASSERT(sizeof(struct ofp_table_stats) == 56);
+OFP_ASSERT(sizeof(struct ofp_table_stats) == 64);
/* Body of reply to OFPST_PORT request. If a counter is unsupported, set
* the field to all ones. */
struct ofp_vendor {
struct ofp_header header; /* Type OFPT_VENDOR. */
uint32_t vendor; /* Vendor ID:
- * - MSB 0: low-order bytes are Ethernet OUI.
+ * - MSB 0: low-order bytes are IEEE OUI.
* - MSB != 0: defined by OpenFlow
* consortium. */
/* Vendor-defined arbitrary additional data. */
ds_put_format(string, " %d: %-8s: ", ts->table_id, name);
ds_put_format(string, "wild=0x%05"PRIx32", ", ntohl(ts->wildcards));
ds_put_format(string, "max=%6"PRIu32", ", ntohl(ts->max_entries));
- ds_put_format(string, "active=%6"PRIu32", ", ntohl(ts->active_count));
- ds_put_format(string, "matched=%6"PRIu64"\n",
- ntohll(ts->matched_count));
+ ds_put_format(string, "active=%"PRIu32"\n", ntohl(ts->active_count));
+ ds_put_cstr(string, " ");
+ ds_put_format(string, "lookup=%"PRIu64", ",
+ ntohll(ts->lookup_count));
+ ds_put_format(string, "matched=%"PRIu64"\n",
+ ntohll(ts->matched_count));
}
}
for (i = 0; i < chain->n_tables; i++) {
struct sw_table *t = chain->tables[i];
struct sw_flow *flow = t->lookup(t, key);
+ t->n_lookup++;
if (flow) {
t->n_matched++;
return flow;
memset(ots->pad, 0, sizeof ots->pad);
ots->max_entries = htonl(stats.max_flows);
ots->active_count = htonl(stats.n_flows);
+ ots->lookup_count = htonll(stats.n_lookup);
ots->matched_count = htonll(stats.n_matched);
}
return 0;
stats->wildcards = 0; /* No wildcards are supported. */
stats->n_flows = th->n_flows;
stats->max_flows = th->bucket_mask + 1;
+ stats->n_lookup = swt->n_lookup;
stats->n_matched = swt->n_matched;
}
stats->wildcards = 0; /* No wildcards are supported. */
stats->n_flows = substats[0].n_flows + substats[1].n_flows;
stats->max_flows = substats[0].max_flows + substats[1].max_flows;
+ stats->n_lookup = swt->n_lookup;
stats->n_matched = swt->n_matched;
}
stats->wildcards = OFPFW_ALL;
stats->n_flows = tl->n_flows;
stats->max_flows = tl->max_flows;
+ stats->n_lookup = swt->n_lookup;
stats->n_matched = swt->n_matched;
}
supported by the table. */
unsigned int n_flows; /* Number of active flows. */
unsigned int max_flows; /* Flow capacity. */
+ unsigned long int n_lookup; /* Number of packets looked up. */
unsigned long int n_matched; /* Number of packets that have hit. */
};
/* A single table of flows. */
struct sw_table {
- /* Keep track of the number of packets that matched this table. To
- * make this 100% accurate, it should be atomic. However, we're
- * primarily concerned about speed. */
- unsigned long int n_matched;
+ /* The number of packets that have been looked up and matched,
+ * respecitvely. To make these 100% accurate, they should be atomic.
+ * However, we're primarily concerned about speed. */
+ unsigned long long n_lookup;
+ unsigned long long n_matched;
/* Searches 'table' for a flow matching 'key', which must not have any
* wildcard fields. Returns the flow if successful, a null pointer