From 290835f9648c9669fb17f3191906026affde8f2b Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 18 Jan 2016 14:47:40 -0800 Subject: [PATCH] ofproto-dpif-rid: Use UUID, not pointer, to identify ofprotos for recirc. An upcoming commit will make it possible to essentially serialize the recirculation state into an OpenFlow message. For that purpose, we can't sensibly pass a "struct ofproto *", but a randomly generated UUID works just as well. Signed-off-by: Ben Pfaff Acked-by: Jarno Rajahalme --- ofproto/ofproto-dpif-rid.c | 9 +++++---- ofproto/ofproto-dpif-rid.h | 5 +++-- ofproto/ofproto-dpif-xlate.c | 22 +++++++++++++++++++--- ofproto/ofproto-dpif.c | 11 +++++++++++ ofproto/ofproto-dpif.h | 4 +++- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/ofproto/ofproto-dpif-rid.c b/ofproto/ofproto-dpif-rid.c index eb80410a1..046419a4c 100644 --- a/ofproto/ofproto-dpif-rid.c +++ b/ofproto/ofproto-dpif-rid.c @@ -130,7 +130,7 @@ recirc_state_hash(const struct recirc_state *state) { uint32_t hash; - hash = hash_pointer(state->ofproto, 0); + hash = uuid_hash(&state->ofproto_uuid); hash = hash_int(state->table_id, hash); if (flow_tnl_dst_is_set(state->metadata.tunnel)) { /* We may leave remainder bytes unhashed, but that is unlikely as @@ -164,7 +164,7 @@ recirc_state_equal(const struct recirc_state *a, const struct recirc_state *b) { return (a->table_id == b->table_id - && a->ofproto == b->ofproto + && uuid_equals(&a->ofproto_uuid, &b->ofproto_uuid) && flow_tnl_equal(a->metadata.tunnel, b->metadata.tunnel) && !memcmp(&a->metadata.metadata, &b->metadata.metadata, sizeof a->metadata - sizeof a->metadata.tunnel) @@ -304,7 +304,7 @@ recirc_alloc_id(struct ofproto_dpif *ofproto) tunnel.ipv6_dst = in6addr_any; struct recirc_state state = { .table_id = TBL_INTERNAL, - .ofproto = ofproto, + .ofproto_uuid = *ofproto_dpif_get_uuid(ofproto), .metadata = { .tunnel = &tunnel, .in_port = OFPP_NONE }, }; return recirc_alloc_id__(&state, recirc_state_hash(&state))->id; @@ -357,8 +357,9 @@ recirc_free_ofproto(struct ofproto_dpif *ofproto, const char *ofproto_name) { struct recirc_id_node *n; + const struct uuid *ofproto_uuid = ofproto_dpif_get_uuid(ofproto); CMAP_FOR_EACH (n, metadata_node, &metadata_map) { - if (n->state.ofproto == ofproto) { + if (uuid_equals(&n->state.ofproto_uuid, ofproto_uuid)) { VLOG_ERR("recirc_id %"PRIu32 " left allocated when ofproto (%s)" " is destructed", n->id, ofproto_name); diff --git a/ofproto/ofproto-dpif-rid.h b/ofproto/ofproto-dpif-rid.h index 654c95c92..04ec03720 100644 --- a/ofproto/ofproto-dpif-rid.h +++ b/ofproto/ofproto-dpif-rid.h @@ -1,5 +1,5 @@ /* - * 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. @@ -25,6 +25,7 @@ #include "ofp-actions.h" #include "ofproto-dpif-mirror.h" #include "ovs-thread.h" +#include "uuid.h" struct ofproto_dpif; struct rule; @@ -135,7 +136,7 @@ struct recirc_state { uint8_t table_id; /* Pipeline context for post-recirculation processing. */ - struct ofproto_dpif *ofproto; /* Post-recirculation bridge. */ + struct uuid ofproto_uuid; /* Post-recirculation bridge. */ struct recirc_metadata metadata; /* Flow metadata. */ union mf_subvalue *stack; /* Stack if any. */ size_t n_stack; diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index e3b46ab56..8ab4b2aeb 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -506,6 +506,8 @@ static void compose_output_action(struct xlate_ctx *, ofp_port_t ofp_port, static struct xbridge *xbridge_lookup(struct xlate_cfg *, const struct ofproto_dpif *); +static struct xbridge *xbridge_lookup_by_uuid(struct xlate_cfg *, + const struct uuid *); static struct xbundle *xbundle_lookup(struct xlate_cfg *, const struct ofbundle *); static struct xport *xport_lookup(struct xlate_cfg *, @@ -1233,6 +1235,19 @@ xbridge_lookup(struct xlate_cfg *xcfg, const struct ofproto_dpif *ofproto) return NULL; } +static struct xbridge * +xbridge_lookup_by_uuid(struct xlate_cfg *xcfg, const struct uuid *uuid) +{ + struct xbridge *xbridge; + + HMAP_FOR_EACH (xbridge, hmap_node, &xcfg->xbridges) { + if (uuid_equals(ofproto_dpif_get_uuid(xbridge->ofproto), uuid)) { + return xbridge; + } + } + return NULL; +} + static struct xbundle * xbundle_lookup(struct xlate_cfg *xcfg, const struct ofbundle *ofbundle) { @@ -3624,7 +3639,7 @@ compose_recirculate_action__(struct xlate_ctx *ctx, uint8_t table) struct recirc_state state = { .table_id = table, - .ofproto = ctx->xbridge->ofproto, + .ofproto_uuid = *ofproto_dpif_get_uuid(ctx->xbridge->ofproto), .metadata = md, .stack = ctx->stack.data, .n_stack = ctx->stack.size / sizeof(union mf_subvalue), @@ -5138,10 +5153,11 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) } /* Set the bridge for post-recirculation processing if needed. */ - if (ctx.xbridge->ofproto != state->ofproto) { + if (!uuid_equals(ofproto_dpif_get_uuid(ctx.xbridge->ofproto), + &state->ofproto_uuid)) { struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp); const struct xbridge *new_bridge - = xbridge_lookup(xcfg, state->ofproto); + = xbridge_lookup_by_uuid(xcfg, &state->ofproto_uuid); if (OVS_UNLIKELY(!new_bridge)) { /* Drop the packet if the bridge cannot be found. */ diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 3281eaa8b..89e06aa9c 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -296,6 +296,10 @@ struct ofproto_dpif { struct ofproto up; struct dpif_backer *backer; + /* Unique identifier for this instantiation of this bridge in this running + * process. */ + struct uuid uuid; + ATOMIC(cls_version_t) tables_version; /* For classifier lookups. */ uint64_t dump_seq; /* Last read of udpif_dump_seq(). */ @@ -1312,6 +1316,7 @@ construct(struct ofproto *ofproto_) return error; } + uuid_generate(&ofproto->uuid); atomic_init(&ofproto->tables_version, CLS_MIN_VERSION); ofproto->netflow = NULL; ofproto->sflow = NULL; @@ -5713,6 +5718,12 @@ ofproto_dpif_delete_internal_flow(struct ofproto_dpif *ofproto, return 0; } +const struct uuid * +ofproto_dpif_get_uuid(const struct ofproto_dpif *ofproto) +{ + return &ofproto->uuid; +} + const struct ofproto_class ofproto_dpif_class = { init, enumerate_types, diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 61a28ea08..0064178dc 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. +/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 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. @@ -178,6 +178,8 @@ int ofproto_dpif_add_internal_flow(struct ofproto_dpif *, struct rule **rulep); int ofproto_dpif_delete_internal_flow(struct ofproto_dpif *, struct match *, int priority); + +const struct uuid *ofproto_dpif_get_uuid(const struct ofproto_dpif *); /* struct rule_dpif has struct rule as it's first member. */ #define RULE_CAST(RULE) ((struct rule *)RULE) -- 2.20.1