struct net_bridge_port *p;
int port_count = 0;
- ofr->datapath_id = cpu_to_be64(dp->id);
+ ofr->datapath_id = cpu_to_be64(dp->id);
- ofr->n_exact = htonl(2 * TABLE_HASH_MAX_FLOWS);
- ofr->n_compression = 0; /* Not supported */
- ofr->n_general = htonl(TABLE_LINEAR_MAX_FLOWS);
- ofr->buffer_mb = htonl(UINT32_MAX);
- ofr->n_buffers = htonl(N_PKT_BUFFERS);
- ofr->capabilities = htonl(OFP_SUPPORTED_CAPABILITIES);
- ofr->actions = htonl(OFP_SUPPORTED_ACTIONS);
+ ofr->n_buffers = htonl(N_PKT_BUFFERS);
+ ofr->n_tables = dp->chain->n_tables;
+ ofr->capabilities = htonl(OFP_SUPPORTED_CAPABILITIES);
+ ofr->actions = htonl(OFP_SUPPORTED_ACTIONS);
+ memset(ofr->pad, 0, sizeof ofr->pad);
list_for_each_entry_rcu (p, &dp->port_list, node) {
fill_port_desc(p, &ofr->ports[port_count]);
dp->chain->tables[i]->stats(dp->chain->tables[i], &stats);
strncpy(ots->name, stats.name, sizeof ots->name);
ots->table_id = i;
+ ots->wildcards = htonl(stats.wildcards);
memset(ots->pad, 0, sizeof ots->pad);
ots->max_entries = htonl(stats.max_flows);
ots->active_count = htonl(stats.n_flows);
{
struct sw_table_dummy *td = (struct sw_table_dummy *) swt;
stats->name = "dummy";
- stats->n_flows = td->n_flows;
+ stats->wildcards = OFPFW_ALL; /* xxx Set this appropriately */
+ stats->n_flows = td->n_flows;
stats->max_flows = td->max_flows;
+ stats->n_matched = swt->n_matched;
}
{
struct sw_table_hash *th = (struct sw_table_hash *) swt;
stats->name = "hash";
- stats->n_flows = th->n_flows;
+ stats->wildcards = 0; /* No wildcards are supported. */
+ stats->n_flows = th->n_flows;
stats->max_flows = th->bucket_mask + 1;
stats->n_matched = swt->n_matched;
}
for (i = 0; i < 2; i++)
table_hash_stats(t2->subtable[i], &substats[i]);
stats->name = "hash2";
- stats->n_flows = substats[0].n_flows + substats[1].n_flows;
+ 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_matched = swt->n_matched;
}
{
struct sw_table_linear *tl = (struct sw_table_linear *) swt;
stats->name = "linear";
- stats->n_flows = tl->n_flows;
+ stats->wildcards = OFPFW_ALL;
+ stats->n_flows = tl->n_flows;
stats->max_flows = tl->max_flows;
stats->n_matched = swt->n_matched;
}
/* Table statistics. */
struct sw_table_stats {
- const char *name; /* Human-readable name. */
+ const char *name; /* Human-readable name. */
+ uint32_t wildcards; /* Bitmap of OFPFW_* wildcards that are
+ supported by the table. */
unsigned int n_flows; /* Number of active flows. */
unsigned int max_flows; /* Flow capacity. */
unsigned long int n_matched; /* Number of packets that have hit. */
/* The most significant bit being set in the version field indicates an
* experimental OpenFlow version.
*/
-#define OFP_VERSION 0x89
+#define OFP_VERSION 0x90
#define OFP_MAX_TABLE_NAME_LEN 32
#define OFP_MAX_PORT_NAME_LEN 16
uint64_t datapath_id; /* Datapath unique ID. Only the lower 48-bits
are meaningful. */
- /* Table info. */
- uint32_t n_exact; /* Max exact-match table entries. */
- uint32_t n_compression; /* Max entries compressed on service port. */
- uint32_t n_general; /* Max entries of arbitrary form. */
-
- /* Buffer limits. A datapath that cannot buffer reports 0.*/
- uint32_t buffer_mb; /* Space for buffering packets, in MB. */
uint32_t n_buffers; /* Max packets buffered at once. */
+ uint8_t n_tables; /* Number of tables supported by datapath. */
+ uint8_t pad[3]; /* Align to 64-bits. */
+
/* Features. */
uint32_t capabilities; /* Bitmap of support "ofp_capabilities". */
uint32_t actions; /* Bitmap of supported "ofp_action_type"s. */
- uint8_t pad[4]; /* Align to 64-bits. */
/* Port info.*/
struct ofp_phy_port ports[0]; /* Port definitions. The number of ports
is inferred from the length field in
the header. */
};
-OFP_ASSERT(sizeof(struct ofp_switch_features) == 48);
+OFP_ASSERT(sizeof(struct ofp_switch_features) == 32);
/* What changed about the physical port */
enum ofp_port_reason {
enum ofp_flow_mod_command {
OFPFC_ADD, /* New flow. */
+ OFPFC_MODIFY, /* Modify all matching flows. */
+ OFPFC_MODIFY_STRICT, /* Strictly match wildcards and priority. */
OFPFC_DELETE, /* Delete all matching flows. */
OFPFC_DELETE_STRICT /* Strictly match wildcards and priority. */
};
/* Body of reply to OFPST_TABLE request. */
struct ofp_table_stats {
- uint8_t table_id;
+ uint8_t table_id; /* Identifier of table. Lower numbered tables
+ are consulted first. */
uint8_t pad[3]; /* Align to 32-bits */
char name[OFP_MAX_TABLE_NAME_LEN];
+ uint32_t wildcards; /* Bitmap of OFPFW_* wildcards that are
+ supported by the table. */
uint32_t max_entries; /* Max number of entries supported */
uint32_t active_count; /* Number of active entries */
- uint8_t pad2[4]; /* Align to 64 bits. */
uint64_t matched_count; /* Number of packets that hit table */
};
OFP_ASSERT(sizeof(struct ofp_table_stats) == 56);
int i;
ds_put_format(string, "dp id:%"PRIx64"\n", ntohll(osf->datapath_id));
- ds_put_format(string, "tables: exact:%d, compressed:%d, general:%d\n",
- ntohl(osf->n_exact),
- ntohl(osf->n_compression), ntohl(osf->n_general));
- ds_put_format(string, "buffers: size:%d, number:%d\n",
- ntohl(osf->buffer_mb), ntohl(osf->n_buffers));
+ ds_put_format(string, "n_tables:%d, n_buffers:%d\n", osf->n_tables,
+ ntohl(osf->n_buffers));
ds_put_format(string, "features: capabilities:%#x, actions:%#x\n",
ntohl(osf->capabilities), ntohl(osf->actions));
strncpy(name, ts->name, sizeof name);
name[OFP_MAX_TABLE_NAME_LEN] = '\0';
- ds_put_format(string, " table %"PRIu8": ", ts->table_id);
- ds_put_format(string, "name %-8s, ", name);
- 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",
+ 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));
}
}
ofr = make_openflow_reply(sizeof *ofr, OFPT_FEATURES_REPLY,
sender, &buffer);
- ofr->datapath_id = htonll(dp->id);
- ofr->n_exact = htonl(2 * TABLE_HASH_MAX_FLOWS);
- ofr->n_compression = 0; /* Not supported */
- ofr->n_general = htonl(TABLE_LINEAR_MAX_FLOWS);
- ofr->buffer_mb = htonl(UINT32_MAX);
- ofr->n_buffers = htonl(N_PKT_BUFFERS);
- ofr->capabilities = htonl(OFP_SUPPORTED_CAPABILITIES);
- ofr->actions = htonl(OFP_SUPPORTED_ACTIONS);
+ ofr->datapath_id = htonll(dp->id);
+ ofr->n_tables = dp->chain->n_tables;
+ ofr->n_buffers = htonl(N_PKT_BUFFERS);
+ ofr->capabilities = htonl(OFP_SUPPORTED_CAPABILITIES);
+ ofr->actions = htonl(OFP_SUPPORTED_ACTIONS);
LIST_FOR_EACH (p, struct sw_port, node, &dp->port_list) {
struct ofp_phy_port *opp = buffer_put_uninit(buffer, sizeof *opp);
memset(opp, 0, sizeof *opp);
dp->chain->tables[i]->stats(dp->chain->tables[i], &stats);
strncpy(ots->name, stats.name, sizeof ots->name);
ots->table_id = i;
+ ots->wildcards = htonl(stats.wildcards);
memset(ots->pad, 0, sizeof ots->pad);
ots->max_entries = htonl(stats.max_flows);
ots->active_count = htonl(stats.n_flows);
{
struct sw_table_hash *th = (struct sw_table_hash *) swt;
stats->name = "hash";
- stats->n_flows = th->n_flows;
+ stats->wildcards = 0; /* No wildcards are supported. */
+ stats->n_flows = th->n_flows;
stats->max_flows = th->bucket_mask + 1;
stats->n_matched = swt->n_matched;
}
for (i = 0; i < 2; i++)
table_hash_stats(t2->subtable[i], &substats[i]);
stats->name = "hash2";
- stats->n_flows = substats[0].n_flows + substats[1].n_flows;
+ 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_matched = swt->n_matched;
}
{
struct sw_table_linear *tl = (struct sw_table_linear *) swt;
stats->name = "linear";
- stats->n_flows = tl->n_flows;
+ stats->wildcards = OFPFW_ALL;
+ stats->n_flows = tl->n_flows;
stats->max_flows = tl->max_flows;
stats->n_matched = swt->n_matched;
}
/* Table statistics. */
struct sw_table_stats {
const char *name; /* Human-readable name. */
+ uint32_t wildcards; /* Bitmap of OFPFW_* wildcards that are
+ supported by the table. */
unsigned int n_flows; /* Number of active flows. */
unsigned int max_flows; /* Flow capacity. */
unsigned long int n_matched; /* Number of packets that have hit. */