X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ofproto%2Fofproto-dpif-rid.h;h=4bbc7bf89a9244725c9f4c3ceb198240cf3cb32d;hb=1b43cf9e68f4dd0dab4f9d3fa9dd80aeb642c139;hp=e7d95bf145a7dd77fa77e2cd60d1a1b359886f14;hpb=597819523ca5b5641653c410c2f13f364352677f;p=cascardo%2Fovs.git diff --git a/ofproto/ofproto-dpif-rid.h b/ofproto/ofproto-dpif-rid.h index e7d95bf14..4bbc7bf89 100644 --- a/ofproto/ofproto-dpif-rid.h +++ b/ofproto/ofproto-dpif-rid.h @@ -93,7 +93,7 @@ struct rule; /* 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 == 33); +BUILD_ASSERT_DECL(FLOW_WC_SEQ == 35); struct recirc_metadata { /* Metadata in struct flow. */ @@ -120,7 +120,7 @@ static inline void recirc_metadata_to_flow(const struct recirc_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); @@ -142,6 +142,7 @@ struct recirc_state { struct recirc_metadata metadata; /* Flow metadata. */ struct ofpbuf *stack; /* Stack if any. */ mirror_mask_t mirrors; /* Mirrors already output. */ + bool conntracked; /* Conntrack occurred prior to recirc. */ /* Actions to be translated on recirculation. */ uint32_t action_set_len; /* How much of 'ofpacts' consists of an @@ -195,4 +196,67 @@ void recirc_id_node_unref(const struct recirc_id_node *); void recirc_run(void); +/* Recirculation IDs on which references are held. */ +struct recirc_refs { + unsigned n_recircs; + union { + uint32_t recirc[2]; /* When n_recircs == 1 or 2 */ + uint32_t *recircs; /* When 'n_recircs' > 2 */ + }; +}; + +#define RECIRC_REFS_EMPTY_INITIALIZER ((struct recirc_refs) \ + { 0, { { 0, 0 } } }) +/* Helpers to abstract the recirculation union away. */ +static inline void +recirc_refs_init(struct recirc_refs *rr) +{ + *rr = RECIRC_REFS_EMPTY_INITIALIZER; +} + +static inline void +recirc_refs_add(struct recirc_refs *rr, uint32_t id) +{ + if (OVS_LIKELY(rr->n_recircs < ARRAY_SIZE(rr->recirc))) { + rr->recirc[rr->n_recircs++] = id; + } else { + if (rr->n_recircs == ARRAY_SIZE(rr->recirc)) { + uint32_t *recircs = xmalloc(sizeof rr->recirc + sizeof id); + + memcpy(recircs, rr->recirc, sizeof rr->recirc); + rr->recircs = recircs; + } else { + rr->recircs = xrealloc(rr->recircs, + (rr->n_recircs + 1) * sizeof id); + } + rr->recircs[rr->n_recircs++] = id; + } +} + +static inline void +recirc_refs_swap(struct recirc_refs *a, struct recirc_refs *b) +{ + struct recirc_refs tmp; + + tmp = *a; + *a = *b; + *b = tmp; +} + +static inline void +recirc_refs_unref(struct recirc_refs *rr) +{ + if (OVS_LIKELY(rr->n_recircs <= ARRAY_SIZE(rr->recirc))) { + for (int i = 0; i < rr->n_recircs; i++) { + recirc_free_id(rr->recirc[i]); + } + } else { + for (int i = 0; i < rr->n_recircs; i++) { + recirc_free_id(rr->recircs[i]); + } + free(rr->recircs); + } + rr->n_recircs = 0; +} + #endif