2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

ofproto: Add ref counting for variable length mf_fields.

Currently, a controller may potentially trigger a segmentation fault if it
accidentally removes a TLV mapping that is still used by an active flow.
To resolve this issue, in this patch, we maintain reference counting for each
dynamically allocated variable length mf_fields, so that vswitchd can use this
information to properly remove a TLV mapping, and to return an error if the
controller tries to remove a TLV mapping that is still used by any active flow.

To keep track of the usage of tun_metadata for each flow, two 'uint64_t'
bitmaps are introduce for the flow match and flow action respectively. We use
'uint64_t' as a bitmap since the 64 geneve TLV tunnel metadata are the only
available variable length mf_fields for now. We shall adopt general bitmap when
more variable length mf_fields are introduced. The bitmaps are configured
during the flow decoding process, and vswitchd use these bitmaps to increase or
decrease the ref counting when the flow is created or deleted.

VMWare-BZ: #1768370
Fixes: 04f48a68c4 ("ofp-actions: Fix variable length meta-flow OXMs.")
Suggested-by: Jarno Rajahalme <jarno@ovn.org>
Suggested-by: Joe Stringer <joe@ovn.org>
Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
Signed-off-by: Joe Stringer <joe@ovn.org>
This commit is contained in:
Yi-Hung Wei
2017-03-13 11:28:21 -07:00
committed by Joe Stringer
parent 3cddeff01c
commit 5c7c16d896
14 changed files with 485 additions and 143 deletions

View File

@@ -29,6 +29,7 @@
#include "openvswitch/ofp-errors.h"
#include "openvswitch/ofp-util.h"
#include "openvswitch/ofpbuf.h"
#include "vl-mff-map.h"
#include "unaligned.h"
@@ -108,6 +109,7 @@ learn_execute(const struct ofpact_learn *learn, const struct flow *flow,
fm->importance = 0;
fm->buffer_id = UINT32_MAX;
fm->out_port = OFPP_NONE;
fm->ofpacts_tlv_bitmap = 0;
fm->flags = 0;
if (learn->flags & NX_LEARN_F_SEND_FLOW_REM) {
fm->flags |= OFPUTIL_FF_SEND_FLOW_REM;
@@ -137,6 +139,8 @@ learn_execute(const struct ofpact_learn *learn, const struct flow *flow,
switch (spec->dst_type) {
case NX_LEARN_DST_MATCH:
mf_write_subfield(&spec->dst, &value, &fm->match);
mf_vl_mff_set_tlv_bitmap(
spec->dst.field, &fm->match.flow.tunnel.metadata.present.map);
break;
case NX_LEARN_DST_LOAD:
@@ -146,6 +150,7 @@ learn_execute(const struct ofpact_learn *learn, const struct flow *flow,
spec->n_bits);
bitwise_one(ofpact_set_field_mask(sf), spec->dst.field->n_bytes,
spec->dst.ofs, spec->n_bits);
mf_vl_mff_set_tlv_bitmap(spec->dst.field, &fm->ofpacts_tlv_bitmap);
break;
case NX_LEARN_DST_OUTPUT: