summaryrefslogtreecommitdiff
path: root/build-aux
diff options
context:
space:
mode:
authorYi-Hung Wei <yihung.wei@gmail.com>2017-01-20 15:12:21 -0800
committerJoe Stringer <joe@ovn.org>2017-02-01 13:05:34 -0800
commit04f48a68c42851348ad0ff6105c79b32f26c050a (patch)
treecc0d424c83e34a3bc66b5d8ea8acfc5780b4b011 /build-aux
parentdc2dab6e6de50a6b6ef25eb2cf761fae3a3a33a7 (diff)
downloadopenvswitch-04f48a68c42851348ad0ff6105c79b32f26c050a.tar.gz
ofp-actions: Fix variable length meta-flow OXMs.
Previously, if a flow action that involves a tunnel metadata meta-flow field is dumped from vswitchd, the replied field length in the OXM header is filled with the maximum possible field length, instead of the length configured in the tunnel TLV mapping table. To solve this issue, this patch introduces the following changes. In order to maintain the correct length of variable length mf_fields (i.e. tun_metadata), this patch creates a per-switch based map (struct vl_mff_map) that hosts the variable length mf_fields. This map is updated when a controller adds/deletes tlv-mapping entries to/from a switch. Although the per-swtch based vl_mff_map only hosts tun_metadata for now, it is able to support new variable length mf_fields in the future. With this commit, when a switch decodes a flow action with mf_field, the switch firstly looks up the global mf_fields map to identify the mf_field type. For the variable length mf_fields, the switch uses the vl_mff_map to get the configured mf_field entries. By lookig up vl_mff_map, the switch can check if the added flow action access beyond the configured size of a variable length mf_field, and the switch reports an ofperr if the controller adds a flow with unmapped variable length mf_field. Later on, when a controller request flows from the switch, with the per-switch based mf_fields, the switch will encode the OXM header with correct length for variable length mf_fields. To use the vl_mff_map for decoding flow actions, extract-ofp-actions is updated to pass the vl_mff_map to the required action decoding functions. Also, a new error code is introduced to identify a flow with an invalid variable length mf_field. Moreover, a testcase is added to prevent future regressions. Committer notes: - Factor out common code - Style fixups - Rename OFPERR_NXFMFC_INVALID_VL_MFF -> OFPERR_NXFMFC_INVALID_TLV_FIELD VMWare-BZ: #1768370 Reported-by: Harold Lim <haroldl@vmware.com> Suggested-by: Joe Stringer <joe@ovn.org> Suggested-by: Jarno Rajahalme <jarno@ovn.org> Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com> Signed-off-by: Joe Stringer <joe@ovn.org>
Diffstat (limited to 'build-aux')
-rwxr-xr-xbuild-aux/extract-ofp-actions46
-rwxr-xr-xbuild-aux/extract-ofp-fields4
2 files changed, 33 insertions, 17 deletions
diff --git a/build-aux/extract-ofp-actions b/build-aux/extract-ofp-actions
index 3a7234943..184447b99 100755
--- a/build-aux/extract-ofp-actions
+++ b/build-aux/extract-ofp-actions
@@ -123,7 +123,13 @@ def extract_ofp_actions(fn, definitions):
fatal("unexpected syntax between actions")
dsts = m.group(1)
- argtype = m.group(2).strip().replace('.', '', 1)
+ argtypes = m.group(2).strip().replace('.', '', 1)
+
+ if 'VLMFF' in argtypes:
+ arg_vl_mff_map = True
+ else:
+ arg_vl_mff_map = False
+ argtype = argtypes.replace('VLMFF', '', 1).rstrip()
get_line()
m = re.match(r'\s+(([A-Z]+)_RAW([0-9]*)_([A-Z0-9_]+)),?', line)
@@ -210,17 +216,18 @@ def extract_ofp_actions(fn, definitions):
else:
max_length = min_length
- info = {"enum": enum, # 0
- "deprecation": deprecation, # 1
- "file_name": file_name, # 2
- "line_number": line_number, # 3
- "min_length": min_length, # 4
- "max_length": max_length, # 5
- "arg_ofs": arg_ofs, # 6
- "arg_len": arg_len, # 7
- "base_argtype": base_argtype, # 8
- "version": version, # 9
- "type": type_} # 10
+ info = {"enum": enum, # 0
+ "deprecation": deprecation, # 1
+ "file_name": file_name, # 2
+ "line_number": line_number, # 3
+ "min_length": min_length, # 4
+ "max_length": max_length, # 5
+ "arg_ofs": arg_ofs, # 6
+ "arg_len": arg_len, # 7
+ "base_argtype": base_argtype, # 8
+ "arg_vl_mff_map": arg_vl_mff_map, # 9
+ "version": version, # 10
+ "type": type_} # 11
domain[vendor][type_][version] = info
enums.setdefault(enum, [])
@@ -314,7 +321,8 @@ def extract_ofp_actions(fn, definitions):
print """\
static enum ofperr
ofpact_decode(const struct ofp_action_header *a, enum ofp_raw_action_type raw,
- enum ofp_version version, uint64_t arg, struct ofpbuf *out)
+ enum ofp_version version, uint64_t arg,
+ const struct vl_mff_map *vl_mff_map, struct ofpbuf *out)
{
switch (raw) {\
"""
@@ -322,6 +330,7 @@ ofpact_decode(const struct ofp_action_header *a, enum ofp_raw_action_type raw,
enum = versions[0]["enum"]
print " case %s:" % enum
base_argtype = versions[0]["base_argtype"]
+ arg_vl_mff_map = versions[0]["arg_vl_mff_map"]
if base_argtype == 'void':
print " return decode_%s(out);" % enum
else:
@@ -333,7 +342,10 @@ ofpact_decode(const struct ofp_action_header *a, enum ofp_raw_action_type raw,
arg = "%s(arg)" % hton
else:
arg = "arg"
- print " return decode_%s(%s, version, out);" % (enum, arg)
+ if arg_vl_mff_map:
+ print " return decode_%s(%s, version, vl_mff_map, out);" % (enum, arg)
+ else:
+ print " return decode_%s(%s, version, out);" % (enum, arg)
print
print """\
default:
@@ -346,11 +358,14 @@ ofpact_decode(const struct ofp_action_header *a, enum ofp_raw_action_type raw,
enum = versions[0]["enum"]
prototype = "static enum ofperr decode_%s(" % enum
base_argtype = versions[0]["base_argtype"]
+ arg_vl_mff_map = versions[0]["arg_vl_mff_map"]
if base_argtype != 'void':
if base_argtype.startswith('struct'):
prototype += "const %s *, enum ofp_version, " % base_argtype
else:
prototype += "%s, enum ofp_version, " % base_argtype
+ if arg_vl_mff_map:
+ prototype += 'const struct vl_mff_map *, '
prototype += "struct ofpbuf *);"
print prototype
@@ -358,7 +373,8 @@ ofpact_decode(const struct ofp_action_header *a, enum ofp_raw_action_type raw,
static enum ofperr ofpact_decode(const struct ofp_action_header *,
enum ofp_raw_action_type raw,
enum ofp_version version,
- uint64_t arg, struct ofpbuf *out);
+ uint64_t arg, const struct vl_mff_map *vl_mff_map,
+ struct ofpbuf *out);
"""
if __name__ == '__main__':
diff --git a/build-aux/extract-ofp-fields b/build-aux/extract-ofp-fields
index 333d90ec3..40f1bb287 100755
--- a/build-aux/extract-ofp-fields
+++ b/build-aux/extract-ofp-fields
@@ -334,7 +334,7 @@ def make_meta_flow(meta_flow_h):
rw = 'true'
else:
rw = 'false'
- output += [" %s, %s, %s, %s,"
+ output += [" %s, %s, %s, %s, false,"
% (f['mask'], f['string'], PREREQS[f['prereqs']], rw)]
oxm = f['OXM']
@@ -386,7 +386,7 @@ def make_meta_flow(meta_flow_h):
else:
output += [" -1, /* not usable for prefix lookup */"]
- output += ["},"]
+ output += [" {OVSRCU_INITIALIZER(NULL)},},"]
for oline in output:
print(oline)