diff options
Diffstat (limited to 'ofproto/ofproto-dpif-xlate.h')
-rw-r--r-- | ofproto/ofproto-dpif-xlate.h | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index a53fa8e4d..6c8ade308 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -21,6 +21,7 @@ #include "odp-util.h" #include "ofpbuf.h" #include "ofproto-dpif-mirror.h" +#include "ofproto-dpif-rid.h" #include "ofproto-dpif.h" #include "ofproto.h" #include "stp.h" @@ -36,12 +37,6 @@ struct mac_learning; struct mcast_snooping; struct xlate_cache; -struct xlate_recirc { - uint32_t recirc_id; /* !0 Use recirculation instead of output. */ - uint8_t hash_alg; /* !0 Compute hash for recirc before. */ - uint32_t hash_basis; /* Compute hash for recirc before. */ -}; - struct xlate_out { /* Wildcards relevant in translation. Any fields that were used to * calculate the action must be set for caching and kernel @@ -60,11 +55,72 @@ struct xlate_out { ofp_port_t nf_output_iface; /* Output interface index for NetFlow. */ mirror_mask_t mirrors; /* Bitmap of associated mirrors. */ + /* Recirculation IDs on which references are held. */ + unsigned n_recircs; + union { + uint32_t recirc[2]; /* When n_recircs == 1 or 2 */ + uint32_t *recircs; /* When 'n_recircs' > 2 */ + }; + uint64_t odp_actions_stub[256 / 8]; struct ofpbuf odp_actions_buf; struct ofpbuf *odp_actions; }; +/* Helpers to abstract the recirculation union away. */ +static inline void +xlate_out_add_recirc(struct xlate_out *xout, uint32_t id) +{ + if (OVS_LIKELY(xout->n_recircs < ARRAY_SIZE(xout->recirc))) { + xout->recirc[xout->n_recircs++] = id; + } else { + if (xout->n_recircs == ARRAY_SIZE(xout->recirc)) { + uint32_t *recircs = xmalloc(sizeof xout->recirc + sizeof id); + + memcpy(recircs, xout->recirc, sizeof xout->recirc); + xout->recircs = recircs; + } else { + xout->recircs = xrealloc(xout->recircs, + (xout->n_recircs + 1) * sizeof id); + } + xout->recircs[xout->n_recircs++] = id; + } +} + +static inline const uint32_t * +xlate_out_get_recircs(const struct xlate_out *xout) +{ + if (OVS_LIKELY(xout->n_recircs <= ARRAY_SIZE(xout->recirc))) { + return xout->recirc; + } else { + return xout->recircs; + } +} + +static inline void +xlate_out_take_recircs(struct xlate_out *xout) +{ + if (OVS_UNLIKELY(xout->n_recircs > ARRAY_SIZE(xout->recirc))) { + free(xout->recircs); + } + xout->n_recircs = 0; +} + +static inline void +xlate_out_free_recircs(struct xlate_out *xout) +{ + if (OVS_LIKELY(xout->n_recircs <= ARRAY_SIZE(xout->recirc))) { + for (int i = 0; i < xout->n_recircs; i++) { + recirc_free_id(xout->recirc[i]); + } + } else { + for (int i = 0; i < xout->n_recircs; i++) { + recirc_free_id(xout->recircs[i]); + } + free(xout->recircs); + } +} + struct xlate_in { struct ofproto_dpif *ofproto; @@ -143,6 +199,10 @@ struct xlate_in { * odp_actions stored in xlate_out. If NULL, the default buffer will be * used. */ struct ofpbuf *odp_actions; + + /* The recirculation context related to this translation, as returned by + * xlate_lookup. */ + const struct recirc_id_node *recirc; }; void xlate_ofproto_set(struct ofproto_dpif *, const char *name, struct dpif *, |