/*
- * Copyright (c) 2014, 2015 Nicira, Inc.
+ * Copyright (c) 2014, 2015, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "ofp-actions.h"
#include "ofproto-dpif-mirror.h"
#include "ovs-thread.h"
+#include "uuid.h"
struct ofproto_dpif;
struct rule;
/*
- * Recirculation
- * =============
+ * Freezing and recirculation
+ * ==========================
+ *
+ * Freezing is a technique for halting and checkpointing packet translation in
+ * a way that it can be restarted again later. This file has a couple of data
+ * structures related to freezing in general; their names begin with "frozen".
+ *
+ * Recirculation is the use of freezing to allow a frame to re-enter the
+ * datapath packet processing path to achieve more flexible packet processing,
+ * such as modifying header fields after MPLS POP action and selecting a slave
+ * port for bond ports.
*
- * Recirculation is a technique to allow a frame to re-enter the datapath
- * packet processing path to achieve more flexible packet processing, such as
- * modifying header fields after MPLS POP action and selecting a slave port for
- * bond ports.
*
* Data path and user space interface
* -----------------------------------
/* Metadata for restoring pipeline context after recirculation. Helpers
* are inlined below to keep them together with the definition for easier
* updates. */
-BUILD_ASSERT_DECL(FLOW_WC_SEQ == 34);
+BUILD_ASSERT_DECL(FLOW_WC_SEQ == 35);
-struct recirc_metadata {
+struct frozen_metadata {
/* Metadata in struct flow. */
const struct flow_tnl *tunnel; /* Encapsulating tunnel parameters. */
ovs_be64 metadata; /* OpenFlow Metadata. */
uint64_t regs[FLOW_N_XREGS]; /* Registers. */
ofp_port_t in_port; /* Incoming port. */
- ofp_port_t actset_output; /* Output port in action set. */
};
static inline void
-recirc_metadata_from_flow(struct recirc_metadata *md,
+frozen_metadata_from_flow(struct frozen_metadata *md,
const struct flow *flow)
{
memset(md, 0, sizeof *md);
md->metadata = flow->metadata;
memcpy(md->regs, flow->regs, sizeof md->regs);
md->in_port = flow->in_port.ofp_port;
- md->actset_output = flow->actset_output;
}
static inline void
-recirc_metadata_to_flow(const struct recirc_metadata *md,
+frozen_metadata_to_flow(const struct frozen_metadata *md,
struct flow *flow)
{
- if (md->tunnel && md->tunnel->ip_dst) {
+ if (md->tunnel && flow_tnl_dst_is_set(md->tunnel)) {
flow->tunnel = *md->tunnel;
} else {
memset(&flow->tunnel, 0, sizeof flow->tunnel);
flow->metadata = md->metadata;
memcpy(flow->regs, md->regs, sizeof flow->regs);
flow->in_port.ofp_port = md->in_port;
- flow->actset_output = md->actset_output;
}
-/* State that flow translation can save, to restore when recirculation
- * occurs. */
-struct recirc_state {
- /* Initial table for post-recirculation processing. */
+/* State that flow translation can save, to restore when translation
+ * resumes. */
+struct frozen_state {
+ /* Initial table for processing when thawing. */
uint8_t table_id;
- /* Pipeline context for post-recirculation processing. */
- struct ofproto_dpif *ofproto; /* Post-recirculation bridge. */
- struct recirc_metadata metadata; /* Flow metadata. */
- struct ofpbuf *stack; /* Stack if any. */
+ /* Pipeline context for processing when thawing. */
+ struct uuid ofproto_uuid; /* Bridge to resume from. */
+ struct frozen_metadata metadata; /* Flow metadata. */
+ union mf_subvalue *stack; /* Stack if any. */
+ size_t n_stack;
mirror_mask_t mirrors; /* Mirrors already output. */
- bool conntracked; /* Conntrack occurred prior to recirc. */
+ bool conntracked; /* Conntrack occurred prior to freeze. */
- /* Actions to be translated on recirculation. */
- uint32_t action_set_len; /* How much of 'ofpacts' consists of an
- * action set? */
- uint32_t ofpacts_len; /* Size of 'ofpacts', in bytes. */
- struct ofpact *ofpacts; /* Sequence of "struct ofpacts". */
+ /* Actions to be translated when thawing. */
+ struct ofpact *ofpacts;
+ size_t ofpacts_len; /* Size of 'ofpacts', in bytes. */
+ struct ofpact *action_set;
+ size_t action_set_len; /* Size of 'action_set', in bytes. */
};
/* This maps a recirculation ID to saved state that flow translation can
*
* This state should not be modified after inserting a node in the pool,
* hence the 'const' to emphasize that. */
- const struct recirc_state state;
+ const struct frozen_state state;
/* Storage for tunnel metadata. */
struct flow_tnl state_metadata_tunnel;
* updated to use this mechanism instead of internal rules. */
uint32_t recirc_alloc_id(struct ofproto_dpif *);
-uint32_t recirc_alloc_id_ctx(const struct recirc_state *);
-uint32_t recirc_find_id(const struct recirc_state *);
+uint32_t recirc_alloc_id_ctx(const struct frozen_state *);
+uint32_t recirc_find_id(const struct frozen_state *);
void recirc_free_id(uint32_t recirc_id);
void recirc_free_ofproto(struct ofproto_dpif *, const char *ofproto_name);
const struct recirc_id_node *recirc_id_node_find(uint32_t recirc_id);
+static inline struct recirc_id_node *
+recirc_id_node_from_state(const struct frozen_state *state)
+{
+ return CONTAINER_OF(state, struct recirc_id_node, state);
+}
+
static inline bool recirc_id_node_try_ref_rcu(const struct recirc_id_node *n_)
{
struct recirc_id_node *node = CONST_CAST(struct recirc_id_node *, n_);