From: kmindg Date: Sun, 9 Mar 2014 09:48:04 +0000 (+0800) Subject: ofproto: Update rule's priority in eviction group. X-Git-Tag: sliver-openvswitch-2.2.90-1~6^2~140 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=6d56c1f19fe9facea0eabc4a39ad01cfc8d7971d ofproto: Update rule's priority in eviction group. We do call heap_rebuild in ofproto_run, but we do not update rule's priority with latest hard_timeout and idle_timeout before heap_rebuild. This patch ensures that rule's priority has been updated before heap_rebuild, and adds two test cases to check eviction with modified hard_timeout and idle_timwout. Signed-off-by: kmindg Signed-off-by: Ben Pfaff --- diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index e691bb93d..45621e962 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1451,19 +1451,23 @@ ofproto_run(struct ofproto *p) } ovs_mutex_lock(&ofproto_mutex); - HEAP_FOR_EACH (evg, size_node, &table->eviction_groups_by_size) { - heap_rebuild(&evg->rules); - } - fat_rwlock_rdlock(&table->cls.rwlock); cls_cursor_init(&cursor, &table->cls, NULL); CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { - if (!rule->eviction_group - && (rule->idle_timeout || rule->hard_timeout)) { - eviction_group_add_rule(rule); + if (rule->idle_timeout || rule->hard_timeout) { + if (!rule->eviction_group) { + eviction_group_add_rule(rule); + } else { + heap_raw_change(&rule->evg_node, + rule_eviction_priority(p, rule)); + } } } fat_rwlock_unlock(&table->cls.rwlock); + + HEAP_FOR_EACH (evg, size_node, &table->eviction_groups_by_size) { + heap_rebuild(&evg->rules); + } ovs_mutex_unlock(&ofproto_mutex); } } diff --git a/tests/ofproto.at b/tests/ofproto.at index f6a62cdb2..eb1680ce7 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -1365,6 +1365,80 @@ OFPST_FLOW reply (OF1.2): OVS_VSWITCHD_STOP AT_CLEANUP +AT_SETUP([ofproto - eviction upon table overflow, with modified hard timeout]) +OVS_VSWITCHD_START +# Configure a maximum of 4 flows. +AT_CHECK( + [ovs-vsctl \ + -- --id=@t0 create Flow_Table flow-limit=4 overflow-policy=evict \ + -- set bridge br0 flow_tables:0=@t0 \ + | ${PERL} $srcdir/uuidfilt.pl], + [0], [<0> +]) +# Add 4 flows. +for in_port in 4 3 2 1; do + ovs-ofctl add-flow br0 hard_timeout=1${in_port},in_port=$in_port,actions=drop +done +AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl + hard_timeout=11, in_port=1 actions=drop + hard_timeout=12, in_port=2 actions=drop + hard_timeout=13, in_port=3 actions=drop + hard_timeout=14, in_port=4 actions=drop +NXST_FLOW reply: +]) +# Sleep and modify the one that expires soonest +sleep 2 +AT_CHECK([ovs-ofctl mod-flows br0 in_port=1,actions=drop]) +sleep 2 +# Adding another flow will cause the one that expires soonest to be evicted. +AT_CHECK([ovs-ofctl add-flow br0 in_port=5,actions=drop]) +AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl + hard_timeout=11, in_port=1 actions=drop + hard_timeout=13, in_port=3 actions=drop + hard_timeout=14, in_port=4 actions=drop + in_port=5 actions=drop +NXST_FLOW reply: +]) +OVS_VSWITCHD_STOP +AT_CLEANUP + +AT_SETUP([ofproto - eviction upon table overflow, with modified idle timeout]) +OVS_VSWITCHD_START([add-port br0 p1 -- set interface p1 type=dummy ofport_request=1]) +# Configure a maximum of 4 flows. +AT_CHECK( + [ovs-vsctl \ + -- --id=@t0 create Flow_Table flow-limit=4 overflow-policy=evict \ + -- set bridge br0 flow_tables:0=@t0 \ + | ${PERL} $srcdir/uuidfilt.pl], + [0], [<0> +]) +# Add 4 flows. +for in_port in 4 3 2 1; do + ovs-ofctl add-flow br0 idle_timeout=1${in_port},in_port=$in_port,actions=drop +done +AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl + idle_timeout=11, in_port=1 actions=drop + idle_timeout=12, in_port=2 actions=drop + idle_timeout=13, in_port=3 actions=drop + idle_timeout=14, in_port=4 actions=drop +NXST_FLOW reply: +]) +# Sleep and receive on the flow that expires soonest +sleep 2 +AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1)']) +sleep 2 +# Adding another flow will cause the one that expires soonest to be evicted. +AT_CHECK([ovs-ofctl add-flow br0 in_port=5,actions=drop]) +AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl + idle_timeout=13, in_port=3 actions=drop + idle_timeout=14, in_port=4 actions=drop + in_port=5 actions=drop + n_packets=1, n_bytes=60, idle_timeout=11, in_port=1 actions=drop +NXST_FLOW reply: +]) +OVS_VSWITCHD_STOP +AT_CLEANUP + AT_SETUP([ofproto - asynchronous message control (OpenFlow 1.0)]) OVS_VSWITCHD_START AT_CHECK([ovs-ofctl -P openflow10 monitor br0 --detach --no-chdir --pidfile])