When deleting a bridge it is currently possible to delete a mater without deleting the rules using the meter first. Fix this by moving the meter's rule deletion to meter_delete().
Signed-off-by: Jarno Rajahalme <ja...@ovn.org> Reported-by: Petr Machata <pe...@mellanox.com> --- ofproto/ofproto.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index d601f71..de1c469 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -6192,10 +6192,22 @@ static void meter_delete(struct ofproto *ofproto, uint32_t first, uint32_t last) OVS_REQUIRES(ofproto_mutex) { - uint32_t mid; - for (mid = first; mid <= last; ++mid) { + for (uint32_t mid = first; mid <= last; ++mid) { struct meter *meter = ofproto->meters[mid]; if (meter) { + /* First delete the rules that use this meter. */ + if (!ovs_list_is_empty(&meter->rules)) { + struct rule_collection rules; + struct rule *rule; + + rule_collection_init(&rules); + + LIST_FOR_EACH (rule, meter_list_node, &meter->rules) { + rule_collection_add(&rules, rule); + } + delete_flows__(&rules, OFPRR_METER_DELETE, NULL); + } + ofproto->meters[mid] = NULL; ofproto->ofproto_class->meter_del(ofproto, meter->provider_meter_id); @@ -6253,7 +6265,6 @@ handle_delete_meter(struct ofconn *ofconn, struct ofputil_meter_mod *mm) { struct ofproto *ofproto = ofconn_get_ofproto(ofconn); uint32_t meter_id = mm->meter.meter_id; - struct rule_collection rules; enum ofperr error = 0; uint32_t first, last; @@ -6267,25 +6278,9 @@ handle_delete_meter(struct ofconn *ofconn, struct ofputil_meter_mod *mm) first = last = meter_id; } - /* First delete the rules that use this meter. If any of those rules are - * currently being modified, postpone the whole operation until later. */ - rule_collection_init(&rules); - ovs_mutex_lock(&ofproto_mutex); - for (meter_id = first; meter_id <= last; ++meter_id) { - struct meter *meter = ofproto->meters[meter_id]; - if (meter && !ovs_list_is_empty(&meter->rules)) { - struct rule *rule; - - LIST_FOR_EACH (rule, meter_list_node, &meter->rules) { - rule_collection_add(&rules, rule); - } - } - } - delete_flows__(&rules, OFPRR_METER_DELETE, NULL); - /* Delete the meters. */ + ovs_mutex_lock(&ofproto_mutex); meter_delete(ofproto, first, last); - ovs_mutex_unlock(&ofproto_mutex); return error; -- 2.1.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev