diff --git a/build-aux/automake.mk b/build-aux/automake.mk index 6267ccd7c..b9a77a51c 100644 --- a/build-aux/automake.mk +++ b/build-aux/automake.mk @@ -5,6 +5,7 @@ EXTRA_DIST += \ build-aux/dist-docs \ build-aux/dpdkstrip.py \ build-aux/generate-dhparams-c \ + build-aux/gen_ofp_field_decoders \ build-aux/initial-tab-allowed-files \ build-aux/sodepends.py \ build-aux/soexpand.py \ @@ -12,7 +13,8 @@ EXTRA_DIST += \ build-aux/xml2nroff FLAKE8_PYFILES += \ - $(srcdir)/build-aux/xml2nroff \ build-aux/dpdkstrip.py \ + build-aux/gen_ofp_field_decoders \ build-aux/sodepends.py \ - build-aux/soexpand.py + build-aux/soexpand.py \ + build-aux/xml2nroff diff --git a/build-aux/gen_ofp_field_decoders b/build-aux/gen_ofp_field_decoders new file mode 100755 index 000000000..96f99e860 --- /dev/null +++ b/build-aux/gen_ofp_field_decoders @@ -0,0 +1,67 @@ +#!/bin/env python + +import argparse + +import build.extract_ofp_fields as extract_fields + + +def main(): + parser = argparse.ArgumentParser( + description="Tool to generate python ofproto field decoders from" + "meta-flow information" + ) + parser.add_argument( + "metaflow", + metavar="FILE", + type=str, + help="Read meta-flow info from file", + ) + + args = parser.parse_args() + + fields = extract_fields.extract_ofp_fields(args.metaflow) + + field_decoders = {} + for field in fields: + decoder = get_decoder(field) + field_decoders[field.get("name")] = decoder + if field.get("extra_name"): + field_decoders[field.get("extra_name")] = decoder + + code = """ +# This file is auto-generated. Do not edit! + +from ovs.flow import decoders + +field_decoders = {{ +{decoders} +}}""".format( + decoders="\n".join( + [ + " '{name}': {decoder},".format(name=name, decoder=decoder) + for name, decoder in field_decoders.items() + ] + ) + ) + print(code) + + +def get_decoder(field): + formatting = field.get("formatting") + if formatting in ["decimal", "hexadecimal"]: + if field.get("mask") == "MFM_NONE": + return "decoders.decode_int" + else: + if field.get("n_bits") in [8, 16, 32, 64, 128, 992]: + return "decoders.Mask{}".format(field.get("n_bits")) + return "decoders.decode_mask({})".format(field.get("n_bits")) + elif formatting in ["IPv4", "IPv6"]: + return "decoders.IPMask" + elif formatting == "Ethernet": + return "decoders.EthMask" + else: + return "decoders.decode_default" + + +if __name__ == "__main__": + main() diff --git a/python/automake.mk b/python/automake.mk index d11a7ade1..72516d0dd 100644 --- a/python/automake.mk +++ b/python/automake.mk @@ -30,6 +30,7 @@ ovs_pyfiles = \ python/ovs/flow/decoders.py \ python/ovs/flow/kv.py \ python/ovs/flow/list.py \ + python/ovs/flow/ofp_fields.py \ python/ovs/json.py \ python/ovs/jsonrpc.py \ python/ovs/ovsuuid.py \ @@ -127,3 +128,9 @@ EXTRA_DIST += python/ovs/dirs.py.template CLEANFILES += python/ovs/dirs.py EXTRA_DIST += python/TODO.rst + +$(srcdir)/python/ovs/flow/ofp_fields.py: $(srcdir)/build-aux/gen_ofp_field_decoders include/openvswitch/meta-flow.h + $(AM_V_GEN)$(run_python) $< $(srcdir)/include/openvswitch/meta-flow.h > $@.tmp + $(AM_V_at)mv $@.tmp $@ +EXTRA_DIST += python/ovs/flow/ofp_fields.py +CLEANFILES += python/ovs/flow/ofp_fields.py diff --git a/python/ovs/.gitignore b/python/ovs/.gitignore index 8bbcd824f..40a63d27d 100644 --- a/python/ovs/.gitignore +++ b/python/ovs/.gitignore @@ -1,2 +1,3 @@ -version.py dirs.py +flow/ofp_fields.py +version.py