X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=eb1f3be8a9e723300dce669a90c05bdea5aac543;hb=a6fcf462476db3385027d3bfcc1d2dc8386e6f2a;hp=659990ecf749662f7442645c8da014d3f41e291f;hpb=88bf179aa3f3fa89822edcd9b882e0f06d39bf08;p=sliver-openvswitch.git diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 659990ecf..eb1f3be8a 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -125,7 +125,7 @@ struct ofoperation { /* OFOPERATION_MODIFY, OFOPERATION_REPLACE: The old actions, if the actions * are changing. */ - struct rule_actions *actions; + const struct rule_actions *actions; /* OFOPERATION_DELETE. */ enum ofp_flow_removed_reason reason; /* Reason flow was removed. */ @@ -1311,9 +1311,9 @@ ofproto_destroy__(struct ofproto *ofproto) ovs_assert(list_is_empty(&ofproto->pending)); destroy_rule_executes(ofproto); - guarded_list_destroy(&ofproto->rule_executes); - delete_group(ofproto, OFPG_ALL); + + guarded_list_destroy(&ofproto->rule_executes); ovs_rwlock_destroy(&ofproto->groups_rwlock); hmap_destroy(&ofproto->groups); @@ -1941,7 +1941,7 @@ ofproto_add_flow(struct ofproto *ofproto, const struct match *match, rule = rule_from_cls_rule(classifier_find_match_exactly( &ofproto->tables[0].cls, match, priority)); if (rule) { - struct rule_actions *actions = rule_get_actions(rule); + const struct rule_actions *actions = rule_get_actions(rule); must_add = !ofpacts_equal(actions->ofpacts, actions->ofpacts_len, ofpacts, ofpacts_len); } else { @@ -1975,14 +1975,13 @@ ofproto_flow_mod(struct ofproto *ofproto, struct ofputil_flow_mod *fm) 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 @@ -2686,38 +2685,30 @@ ofproto_rule_unref(struct rule *rule) static uint32_t get_provider_meter_id(const struct ofproto *, uint32_t of_meter_id); -/* Creates and returns a new 'struct rule_actions', with a ref_count of 1, - * whose actions are a copy of from the 'ofpacts_len' bytes of 'ofpacts'. */ -struct rule_actions * +/* Creates and returns a new 'struct rule_actions', whose actions are a copy + * of from the 'ofpacts_len' bytes of 'ofpacts'. */ +const struct rule_actions * rule_actions_create(const struct ofproto *ofproto, const struct ofpact *ofpacts, size_t ofpacts_len) { struct rule_actions *actions; - actions = xmalloc(sizeof *actions); - actions->ofpacts = xmemdup(ofpacts, ofpacts_len); + actions = xmalloc(sizeof *actions + ofpacts_len); actions->ofpacts_len = ofpacts_len; actions->provider_meter_id = get_provider_meter_id(ofproto, ofpacts_get_meter(ofpacts, ofpacts_len)); + memcpy(actions->ofpacts, ofpacts, ofpacts_len); return actions; } -static void -rule_actions_destroy_cb(struct rule_actions *actions) -{ - free(actions->ofpacts); - free(actions); -} - -/* Decrements 'actions''s ref_count and frees 'actions' if the ref_count - * reaches 0. */ +/* Free the actions after the RCU quiescent period is reached. */ void -rule_actions_destroy(struct rule_actions *actions) +rule_actions_destroy(const struct rule_actions *actions) { if (actions) { - ovsrcu_postpone(rule_actions_destroy_cb, actions); + ovsrcu_postpone(free, CONST_CAST(struct rule_actions *, actions)); } } @@ -3661,7 +3652,7 @@ handle_flow_stats_request(struct ofconn *ofconn, long long int now = time_msec(); struct ofputil_flow_stats fs; long long int created, used, modified; - struct rule_actions *actions; + const struct rule_actions *actions; enum ofputil_flow_mod_flags flags; ovs_mutex_lock(&rule->mutex); @@ -3702,7 +3693,7 @@ static void flow_stats_ds(struct rule *rule, struct ds *results) { uint64_t packet_count, byte_count; - struct rule_actions *actions; + const struct rule_actions *actions; long long int created, used; rule->ofproto->ofproto_class->rule_get_stats(rule, &packet_count, @@ -3962,7 +3953,8 @@ is_flow_deletion_pending(const struct ofproto *ofproto, 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; } } @@ -4244,7 +4236,7 @@ modify_flows__(struct ofproto *ofproto, struct ofconn *ofconn, reset_counters = (fm->flags & OFPUTIL_FF_RESET_COUNTS) != 0; if (actions_changed || reset_counters) { - struct rule_actions *new_actions; + const struct rule_actions *new_actions; op->actions = rule_get_actions(rule); new_actions = rule_actions_create(ofproto, @@ -6342,7 +6334,7 @@ ofopgroup_complete(struct ofopgroup *group) rule->hard_timeout = op->hard_timeout; ovs_mutex_unlock(&rule->mutex); if (op->actions) { - struct rule_actions *old_actions; + const struct rule_actions *old_actions; ovs_mutex_lock(&rule->mutex); old_actions = rule_get_actions(rule); @@ -6918,7 +6910,7 @@ oftable_insert_rule(struct rule *rule) { struct ofproto *ofproto = rule->ofproto; struct oftable *table = &ofproto->tables[rule->table_id]; - struct rule_actions *actions; + const struct rule_actions *actions; bool may_expire; ovs_mutex_lock(&rule->mutex); @@ -7000,25 +6992,30 @@ ofproto_unixctl_init(void) void ofproto_get_vlan_usage(struct ofproto *ofproto, unsigned long int *vlan_bitmap) { + struct match match; + struct cls_rule target; const struct oftable *oftable; + match_init_catchall(&match); + match_set_vlan_vid_masked(&match, htons(VLAN_CFI), htons(VLAN_CFI)); + cls_rule_init(&target, &match, 0); + free(ofproto->vlan_bitmap); ofproto->vlan_bitmap = bitmap_allocate(4096); ofproto->vlans_changed = false; OFPROTO_FOR_EACH_TABLE (oftable, ofproto) { - const struct cls_subtable *table; + struct cls_cursor cursor; + struct rule *rule; fat_rwlock_rdlock(&oftable->cls.rwlock); - HMAP_FOR_EACH (table, hmap_node, &oftable->cls.subtables) { - if (minimask_get_vid_mask(&table->mask) == VLAN_VID_MASK) { - const struct cls_rule *rule; - - HMAP_FOR_EACH (rule, hmap_node, &table->rules) { - uint16_t vid = miniflow_get_vid(&rule->match.flow); - bitmap_set1(vlan_bitmap, vid); - bitmap_set1(ofproto->vlan_bitmap, vid); - } + cls_cursor_init(&cursor, &oftable->cls, &target); + CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { + if (minimask_get_vid_mask(&rule->cr.match.mask) == VLAN_VID_MASK) { + uint16_t vid = miniflow_get_vid(&rule->cr.match.flow); + + bitmap_set1(vlan_bitmap, vid); + bitmap_set1(ofproto->vlan_bitmap, vid); } } fat_rwlock_unlock(&oftable->cls.rwlock);