ofproto_dpif_flow_mod(ctx->xbridge->ofproto, fm);
}
-/* Reduces '*timeout' to no more than 'max'. A value of zero in either case
- * means "infinite". */
-static void
-reduce_timeout(uint16_t max, uint16_t *timeout)
-{
- if (max && (!*timeout || *timeout > max)) {
- *timeout = max;
- }
-}
-
static void
xlate_fin_timeout(struct xlate_ctx *ctx,
const struct ofpact_fin_timeout *oft)
{
if (ctx->xin->tcp_flags & (TCP_FIN | TCP_RST) && ctx->rule) {
- struct rule_dpif *rule = ctx->rule;
-
- ovs_mutex_lock(&rule->up.ofproto->expirable_mutex);
- if (list_is_empty(&rule->up.expirable)) {
- list_insert(&rule->up.ofproto->expirable, &rule->up.expirable);
- }
- ovs_mutex_unlock(&rule->up.ofproto->expirable_mutex);
-
- ovs_mutex_lock(&rule->up.timeout_mutex);
- reduce_timeout(oft->fin_idle_timeout, &rule->up.idle_timeout);
- reduce_timeout(oft->fin_hard_timeout, &rule->up.hard_timeout);
- ovs_mutex_unlock(&rule->up.timeout_mutex);
+ ofproto_rule_reduce_timeouts(&ctx->rule->up, oft->fin_idle_timeout,
+ oft->fin_hard_timeout);
}
}
OVS_RELEASES(rule->evict);
void ofproto_rule_destroy(struct ofproto *, struct classifier *cls,
struct rule *) OVS_REQ_WRLOCK(cls->rwlock);
+void ofproto_rule_reduce_timeouts(struct rule *rule, uint16_t idle_timeout,
+ uint16_t hard_timeout)
+ OVS_EXCLUDED(rule->ofproto->expirable_mutex, rule->timeout_mutex);
bool ofproto_rule_has_out_port(const struct rule *, ofp_port_t out_port);
OVS_TRY_WRLOCK(true, (*rulep)->evict);
static void ofproto_evict(struct ofproto *);
static uint32_t rule_eviction_priority(struct rule *);
+static void eviction_group_add_rule(struct rule *rule);
/* ofport. */
static void ofport_destroy__(struct ofport *);
ofproto->ofproto_class->rule_destruct(rule);
ofopgroup_submit(group);
}
+
+/* Reduces '*timeout' to no more than 'max'. A value of zero in either case
+ * means "infinite". */
+static void
+reduce_timeout(uint16_t max, uint16_t *timeout)
+{
+ if (max && (!*timeout || *timeout > max)) {
+ *timeout = max;
+ }
+}
+
+/* If 'idle_timeout' is nonzero, and 'rule' has no idle timeout or an idle
+ * timeout greater than 'idle_timeout', lowers 'rule''s idle timeout to
+ * 'idle_timeout' seconds. Similarly for 'hard_timeout'.
+ *
+ * Suitable for implementing OFPACT_FIN_TIMEOUT. */
+void
+ofproto_rule_reduce_timeouts(struct rule *rule,
+ uint16_t idle_timeout, uint16_t hard_timeout)
+ OVS_EXCLUDED(rule->ofproto->expirable_mutex, rule->timeout_mutex)
+{
+ if (!idle_timeout && !hard_timeout) {
+ return;
+ }
+
+ ovs_mutex_lock(&rule->ofproto->expirable_mutex);
+ if (list_is_empty(&rule->expirable)) {
+ list_insert(&rule->ofproto->expirable, &rule->expirable);
+ }
+ ovs_mutex_unlock(&rule->ofproto->expirable_mutex);
+
+ ovs_mutex_lock(&rule->timeout_mutex);
+ reduce_timeout(idle_timeout, &rule->idle_timeout);
+ reduce_timeout(hard_timeout, &rule->hard_timeout);
+ ovs_mutex_unlock(&rule->timeout_mutex);
+
+ if (!rule->eviction_group) {
+ eviction_group_add_rule(rule);
+ }
+}
\f
static enum ofperr
handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh)