The OpenFlow OFPFF_CHECK_OVERLAP flag requires us to check whether the flow being inserted overlaps with any existing flows. That isn't efficiently implemented and typically requires us to compare the new flow against most or all of the existing flows. We don't have to do that work if OFPFF_CHECK_OVERLAP is not requested, but commit 0b4f207828c (classifier: Make use of the classifier thread safe.) inadvertently made us do it anyway.
Signed-off-by: Ben Pfaff <b...@nicira.com> --- ofproto/ofproto.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index bbdb2d2..a22cce4 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3345,7 +3345,6 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, struct rule *victim; struct rule *rule; uint8_t table_id; - bool overlaps; int error; error = check_table_id(ofproto, fm->table_id); @@ -3402,13 +3401,18 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, } /* Check for overlap, if requested. */ - ovs_rwlock_rdlock(&table->cls.rwlock); - overlaps = classifier_rule_overlaps(&table->cls, &rule->cr); - ovs_rwlock_unlock(&table->cls.rwlock); - if (fm->flags & OFPFF_CHECK_OVERLAP && overlaps) { - cls_rule_destroy(&rule->cr); - ofproto->ofproto_class->rule_dealloc(rule); - return OFPERR_OFPFMFC_OVERLAP; + if (fm->flags & OFPFF_CHECK_OVERLAP) { + bool overlaps; + + ovs_rwlock_rdlock(&table->cls.rwlock); + overlaps = classifier_rule_overlaps(&table->cls, &rule->cr); + ovs_rwlock_unlock(&table->cls.rwlock); + + if (overlaps) { + cls_rule_destroy(&rule->cr); + ofproto->ofproto_class->rule_dealloc(rule); + return OFPERR_OFPFMFC_OVERLAP; + } } /* FIXME: Implement OFPFF12_RESET_COUNTS */ -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev