};
static void rule_criteria_init(struct rule_criteria *, uint8_t table_id,
- const struct match *match,
- unsigned int priority,
+ const struct match *match, int priority,
ovs_be64 cookie, ovs_be64 cookie_mask,
ofp_port_t out_port, uint32_t out_group);
static void rule_criteria_require_rw(struct rule_criteria *,
{
struct oftable *table;
+ /* This will flush all datapath flows. */
if (ofproto->ofproto_class->flush) {
ofproto->ofproto_class->flush(ofproto);
}
+ /* XXX: There is a small race window here, where new datapath flows can be
+ * created by upcall handlers based on the existing flow table. We can not
+ * call ofproto class flush while holding 'ofproto_mutex' to prevent this,
+ * as then we could deadlock on syncing with the handler threads waiting on
+ * the same mutex. */
+
ovs_mutex_lock(&ofproto_mutex);
OFPROTO_FOR_EACH_TABLE (table, ofproto) {
struct rule *rule;
ofproto_rule_delete__(rule, OFPRR_DELETE);
}
}
+ /* XXX: Concurrent handler threads may insert new learned flows based on
+ * learn actions of the now deleted flows right after we release
+ * 'ofproto_mutex'. */
ovs_mutex_unlock(&ofproto_mutex);
}
static void
flow_mod_init(struct ofputil_flow_mod *fm,
- const struct match *match, unsigned int priority,
+ const struct match *match, int priority,
const struct ofpact *ofpacts, size_t ofpacts_len,
enum ofp_flow_mod_command command)
{
static int
simple_flow_mod(struct ofproto *ofproto,
- const struct match *match, unsigned int priority,
+ const struct match *match, int priority,
const struct ofpact *ofpacts, size_t ofpacts_len,
enum ofp_flow_mod_command command)
{
* This is a helper function for in-band control and fail-open. */
void
ofproto_add_flow(struct ofproto *ofproto, const struct match *match,
- unsigned int priority,
+ int priority,
const struct ofpact *ofpacts, size_t ofpacts_len)
OVS_EXCLUDED(ofproto_mutex)
{
* This is a helper function for in-band control and fail-open. */
void
ofproto_delete_flow(struct ofproto *ofproto,
- const struct match *target, unsigned int priority)
+ const struct match *target, int priority)
OVS_EXCLUDED(ofproto_mutex)
{
struct classifier *cls = &ofproto->tables[0].cls;
struct ofputil_table_features **featuresp,
struct ofputil_table_stats **statsp)
{
- struct mf_bitmap rw_fields = MF_BITMAP_INITIALIZER;
- struct mf_bitmap match = MF_BITMAP_INITIALIZER;
- struct mf_bitmap mask = MF_BITMAP_INITIALIZER;
+ struct mf_bitmap rw_fields = oxm_writable_fields();
+ struct mf_bitmap match = oxm_matchable_fields();
+ struct mf_bitmap mask = oxm_maskable_fields();
struct ofputil_table_features *features;
struct ofputil_table_stats *stats;
int i;
- for (i = 0; i < MFF_N_IDS; i++) {
- const struct mf_field *mf = mf_from_id(i);
-
- if (mf->writable) {
- bitmap_set1(rw_fields.bm, i);
- }
- if (mf->oxm_header || mf->nxm_header) {
- bitmap_set1(match.bm, i);
- if (mf->maskable == MFM_FULLY) {
- bitmap_set1(mask.bm, i);
- }
- }
- }
-
features = *featuresp = xcalloc(ofproto->n_tables, sizeof *features);
for (i = 0; i < ofproto->n_tables; i++) {
struct ofputil_table_features *f = &features[i];
features.n_buffers = pktbuf_capacity();
features.n_tables = ofproto_get_n_visible_tables(ofproto);
features.capabilities = (OFPUTIL_C_FLOW_STATS | OFPUTIL_C_TABLE_STATS |
- OFPUTIL_C_PORT_STATS | OFPUTIL_C_QUEUE_STATS);
+ OFPUTIL_C_PORT_STATS | OFPUTIL_C_QUEUE_STATS |
+ OFPUTIL_C_GROUP_STATS);
if (arp_match_ip) {
features.capabilities |= OFPUTIL_C_ARP_MATCH_IP;
}
* supplied as 0. */
static void
rule_criteria_init(struct rule_criteria *criteria, uint8_t table_id,
- const struct match *match, unsigned int priority,
+ const struct match *match, int priority,
ovs_be64 cookie, ovs_be64 cookie_mask,
ofp_port_t out_port, uint32_t out_group)
{
long long int now = time_msec();
- /* FIXME: Implement OFPFUTIL_FF_RESET_COUNTS */
-
if (change_cookie) {
cookies_remove(ofproto, rule);
}