diff mbox

[ovs-dev,for,p4c-behavioral,1/2] Adding OVS plugin

Message ID 1474285667-14256-2-git-send-email-mshahbaz@cs.princeton.edu
State Changes Requested
Headers show

Commit Message

Muhammad Shahbaz Sept. 19, 2016, 11:47 a.m. UTC
This adds a new plugin, called OVS, in p4c-behavioral. Given a P4 program,
the plugin generates a set of C (macro) code which is called at different
locations within the OVS codebase. The code under the plugin folder reflects the
same directory structure and files in which they are called in the OVS codebase.

---
 .../linux/compat/include/linux/openvswitch.h.h     |  63 +++
 p4c_bm/plugin/ovs/inc/include/openvswitch/flow.h.h |  31 +
 .../ovs/inc/include/openvswitch/meta-flow.h.h      |  74 +++
 .../plugin/ovs/inc/include/openvswitch/packets.h.h |  93 +++
 .../plugin/ovs/inc/include/openvswitch/types.h.h   |  34 ++
 p4c_bm/plugin/ovs/inc/lib/dp-packet.h.h            |  46 ++
 p4c_bm/plugin/ovs/inc/lib/flow.c.h                 | 625 +++++++++++++++++++++
 p4c_bm/plugin/ovs/inc/lib/match.c.h                |  58 ++
 p4c_bm/plugin/ovs/inc/lib/meta-flow.c.h            | 226 ++++++++
 p4c_bm/plugin/ovs/inc/lib/nx-match.c.h             |  60 ++
 p4c_bm/plugin/ovs/inc/lib/odp-execute.c.h          | 130 +++++
 p4c_bm/plugin/ovs/inc/lib/odp-util.c.h             | 251 +++++++++
 p4c_bm/plugin/ovs/inc/lib/packets.c.h              |  63 +++
 p4c_bm/plugin/ovs/inc/lib/packets.h.h              |  51 ++
 .../plugin/ovs/inc/ofproto/ofproto-dpif-sflow.c.h  |  34 ++
 .../plugin/ovs/inc/ofproto/ofproto_dpif_sflow.c.h  |  33 ++
 p4c_bm/smart.py                                    |  77 +++
 17 files changed, 1949 insertions(+)
 create mode 100644 p4c_bm/plugin/ovs/inc/datapath/linux/compat/include/linux/openvswitch.h.h
 create mode 100644 p4c_bm/plugin/ovs/inc/include/openvswitch/flow.h.h
 create mode 100644 p4c_bm/plugin/ovs/inc/include/openvswitch/meta-flow.h.h
 create mode 100644 p4c_bm/plugin/ovs/inc/include/openvswitch/packets.h.h
 create mode 100644 p4c_bm/plugin/ovs/inc/include/openvswitch/types.h.h
 create mode 100644 p4c_bm/plugin/ovs/inc/lib/dp-packet.h.h
 create mode 100644 p4c_bm/plugin/ovs/inc/lib/flow.c.h
 create mode 100644 p4c_bm/plugin/ovs/inc/lib/match.c.h
 create mode 100644 p4c_bm/plugin/ovs/inc/lib/meta-flow.c.h
 create mode 100644 p4c_bm/plugin/ovs/inc/lib/nx-match.c.h
 create mode 100644 p4c_bm/plugin/ovs/inc/lib/odp-execute.c.h
 create mode 100644 p4c_bm/plugin/ovs/inc/lib/odp-util.c.h
 create mode 100644 p4c_bm/plugin/ovs/inc/lib/packets.c.h
 create mode 100644 p4c_bm/plugin/ovs/inc/lib/packets.h.h
 create mode 100644 p4c_bm/plugin/ovs/inc/ofproto/ofproto-dpif-sflow.c.h
 create mode 100644 p4c_bm/plugin/ovs/inc/ofproto/ofproto_dpif_sflow.c.h

--
2.7.4 (Apple Git-66)
diff mbox

Patch

diff --git a/p4c_bm/plugin/ovs/inc/datapath/linux/compat/include/linux/openvswitch.h.h b/p4c_bm/plugin/ovs/inc/datapath/linux/compat/include/linux/openvswitch.h.h
new file mode 100644
index 0000000..678207c
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/datapath/linux/compat/include/linux/openvswitch.h.h
@@ -0,0 +1,63 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_DATAPATH_LINUX_COMPAT_INCLUDE_LINUX_OPENVSWITCH_H_H
+#define	OVS_DATAPATH_LINUX_COMPAT_INCLUDE_LINUX_OPENVSWITCH_H_H 1
+
+/* -- Used in datapath/linux/compat/include/linux/openvswitch.h -- */
+#define OVS_KEY_ATTRS \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    OVS_KEY_ATTR__${header_name.upper()}, \
+//::  #endfor
+    OVS_KEY_ATTR_VALID, \
+    \
+
+/* -- Used in datapath/linux/compat/include/linux/openvswitch.h -- */
+#define OVS_KEY_STRUCTS \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    struct ovs_key__${header_name} { \
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+//::      if bit_width == 8:
+        uint8_t ${field_name}; \
+//::      elif bit_width == 16:
+        ovs_be16 ${field_name}; \
+//::      elif bit_width == 32:
+        ovs_be32 ${field_name}; \
+//::      elif bit_width == 64:
+        ovs_be64 ${field_name}; \
+//::      else:
+        struct ${field_name}_t ${field_name}; \
+//::      #endif
+//::    #endfor
+    }; \
+    \
+//::  #endfor
+    struct ovs_key_valid { \
+//::  for header_name in ordered_header_instances_regular:
+        uint8_t _${header_name}_valid; \
+//::  #endfor
+    }; \
+    \
+
+#endif	/* OVS_DATAPATH_LINUX_COMPAT_INCLUDE_LINUX_OPENVSWITCH_H_H */
diff --git a/p4c_bm/plugin/ovs/inc/include/openvswitch/flow.h.h b/p4c_bm/plugin/ovs/inc/include/openvswitch/flow.h.h
new file mode 100644
index 0000000..97e26e3
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/include/openvswitch/flow.h.h
@@ -0,0 +1,31 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_INCLUDE_OPENVSWITCH_FLOW_H_H
+#define	OVS_INCLUDE_OPENVSWITCH_FLOW_H_H 1
+
+/* -- Used in include/openvswitch/flow.h -- */
+#define OVS_FIELDS \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    struct _${header_name}_padded_header _${header_name}; \
+//::  #endfor
+    struct valid_padded_header valid; \
+    \
+
+#endif	/* OVS_INCLUDE_OPENVSWITCH_FLOW_H_H */
diff --git a/p4c_bm/plugin/ovs/inc/include/openvswitch/meta-flow.h.h b/p4c_bm/plugin/ovs/inc/include/openvswitch/meta-flow.h.h
new file mode 100644
index 0000000..e4b0a0f
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/include/openvswitch/meta-flow.h.h
@@ -0,0 +1,74 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_INCLUDE_OPENVSWITCH_META_FLOW_H_H
+#define	OVS_INCLUDE_OPENVSWITCH_META_FLOW_H_H 1
+
+/* -- Included in include/openvswitch/meta-flow.h -- */
+
+/* NOTE:
+ * 1. Make sure to add preceding tabs in the following fields, otherwise, will result in errors.
+ * 2. For now prerequisites are not handled.
+ * 3. For now all fields are maskable.
+ */
+
+//::  base_oxm_offset = 45 # NOTE: for now we use 45 as the base line offset. If new fixed fields are added in OVS
+//::                       # this number will have to be updated accordingly.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+    /* "${field_name}".
+     *
+     * ${field_name} field.
+     *
+     * Type: be${bit_width}.
+     * Formatting: hexadecimal.
+     * Maskable: bitwise.
+     * Prerequisites: none.
+     * Access: read/write.
+     * NXM: none.
+     * OXM: OXM_OF_${field_name.upper()}(${base_oxm_offset}) since OF1.5 and v2.3.
+     */
+    MFF_${field_name.upper()},
+//::      base_oxm_offset += 1
+
+//::    #endfor
+//::  #endfor
+//::
+//::  for header_name in ordered_header_instances_regular:
+    /* "${header_name}_valid".
+     *
+     * ${header_name}_valid field.
+     *
+     * Type: be${8}.
+     * Formatting: hexadecimal.
+     * Maskable: bitwise.
+     * Prerequisites: none.
+     * Access: read/write.
+     * NXM: none.
+     * OXM: OXM_OF_${header_name.upper()}_VALID(${base_oxm_offset}) since OF1.5 and v2.3.
+     */
+    MFF_${header_name.upper()}_VALID,
+//::      base_oxm_offset += 1
+
+//::  #endfor
+
+/* Do NOT REMOVE THIS. */
+    // MFF_N_IDS
+
+#endif	/* OVS_INCLUDE_OPENVSWITCH_META_FLOW_H_H */
diff --git a/p4c_bm/plugin/ovs/inc/include/openvswitch/packets.h.h b/p4c_bm/plugin/ovs/inc/include/openvswitch/packets.h.h
new file mode 100644
index 0000000..e2c809e
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/include/openvswitch/packets.h.h
@@ -0,0 +1,93 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_INCLUDE_OPENVSWITCH_PACKETS_H_H
+#define	OVS_INCLUDE_OPENVSWITCH_PACKETS_H_H 1
+
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      pass
+//::    else:
+//::      header_len = sum([bit_width for _, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]])/8
+#define _${header_name.upper()}_HEADER_LEN ${header_len}
+//::    #endif
+//::  #endfor
+#define VALID_HEADER_LEN ${len(ordered_header_instances_regular)}
+
+/* -- Used in include/openvswitch/packets.h -- */
+#define OVS_HDR_STRUCTS \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    run_bit_width = 0
+    OVS_PACKED( \
+    struct _${header_name}_header { \
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+//::      if bit_width == 8:
+        uint8_t ${field_name}; \
+//::      elif bit_width == 16:
+        ovs_be16 ${field_name}; \
+//::      elif bit_width == 32:
+        ovs_be32 ${field_name}; \
+//::      elif bit_width == 64:
+        ovs_be64 ${field_name}; \
+//::      else:
+//::        # NOTE: we assume that all fields are, at least, byte aligned.
+        struct ${field_name}_t ${field_name}; \
+//::      #endif
+//::      run_bit_width += bit_width
+//::    #endfor
+    }); \
+    BUILD_ASSERT_DECL(_${header_name.upper()}_HEADER_LEN == sizeof(struct _${header_name}_header)); \
+    \
+    OVS_PACKED( \
+    struct _${header_name}_padded_header { \
+        struct _${header_name}_header hdr; \
+//::    pad_bits = 64 - (run_bit_width % 64)
+//::    pad_bytes = 0
+//::    if pad_bits < 64:
+//::      pad_bytes = pad_bits/8
+        uint8_t pad[${pad_bytes}]; \
+//::    #endif
+    }); \
+    BUILD_ASSERT_DECL( \
+        _${header_name.upper()}_HEADER_LEN+${pad_bytes} == sizeof(struct _${header_name}_padded_header)); \
+    \
+//::  #endfor
+    OVS_PACKED( \
+    struct valid_header { \
+//::  for header_name in ordered_header_instances_regular:
+        uint8_t _${header_name}_valid; \
+//::  #endfor
+    }); \
+    BUILD_ASSERT_DECL(VALID_HEADER_LEN == sizeof(struct valid_header)); \
+    \
+    OVS_PACKED( \
+    struct valid_padded_header { \
+        struct valid_header hdr; \
+//::    pad_bits = 64 - ((len(ordered_header_instances_regular)*8) % 64)
+//::    pad_bytes = 0
+//::    if pad_bits < 64:
+//::      pad_bytes = pad_bits/8
+        uint8_t pad[${pad_bytes}]; \
+//::    #endif
+    }); \
+    BUILD_ASSERT_DECL( \
+        VALID_HEADER_LEN+${pad_bytes} == sizeof(struct valid_padded_header)); \
+    \
+
+#endif	/* OVS_INCLUDE_OPENVSWITCH_PACKETS_H_H */
diff --git a/p4c_bm/plugin/ovs/inc/include/openvswitch/types.h.h b/p4c_bm/plugin/ovs/inc/include/openvswitch/types.h.h
new file mode 100644
index 0000000..92db9cc
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/include/openvswitch/types.h.h
@@ -0,0 +1,34 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_INCLUDE_OPENVSWITCH_TYPES_H_H
+#define	OVS_INCLUDE_OPENVSWITCH_TYPES_H_H 1
+
+/* -- Used in include/openvswitch/types.h -- */
+#define OVS_FIELD_STRUCTS \
+//::  for field_name, bit_width in ordered_field_instances_non_virtual__name_width:
+//::    if field_name.startswith("standard_metadata") or field_name.startswith("intrinsic_metadata"):
+//::      continue
+//::    #endif
+//::    if not (bit_width == 8 or bit_width == 16 or bit_width == 32 or bit_width == 64):
+    struct ${field_name}_t { \
+        uint8_t data[${bit_width}/8]; \
+    }; \
+//::    #endif
+//::  #endfor
+    \
+
+#endif	/* OVS_INCLUDE_OPENVSWITCH_TYPES_H_H */
diff --git a/p4c_bm/plugin/ovs/inc/lib/dp-packet.h.h b/p4c_bm/plugin/ovs/inc/lib/dp-packet.h.h
new file mode 100644
index 0000000..9d2ee13
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/lib/dp-packet.h.h
@@ -0,0 +1,46 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_LIB_DP_PACKET_H_H
+#define	OVS_LIB_DP_PACKET_H_H 1
+
+//:: # NOTE: we don't have to specify metadata in the packet struct in the datapath.
+//:: # The parser can set the value of the metadata but only the final results (after
+//:: # constant propagation) are written in the cache. The only thing different from
+//:: # how native OVS treat metadata is that, in P4/OVS case, parser can set metadata
+//:: # to some arbitrary value, whereas in native OVS, the value of the metadata before
+//:: # being processed by the cache and match-action tables is always 0.
+
+/* -- Used in lib/dp-packet.h -- */
+#define OVS_HDR_ATTRS \
+//::  for header_name in ordered_header_instances_regular:
+    uint16_t _${header_name}_ofs; \
+    uint8_t _${header_name}_valid; \
+//::  #endfor
+    \
+
+/* -- Used in lib/dp-packet.h -- */
+#define OVS_HDR_GET_DP_PACKET_OFS \
+//::  for header_name in ordered_header_instances_regular:
+	static inline void * dp_packet_${header_name}(const struct dp_packet *b) { \
+    	return b->_${header_name}_ofs != UINT16_MAX \
+    		   ? (char *) dp_packet_data(b) + b->_${header_name}_ofs \
+    		   : NULL; \
+    } \
+//::  #endfor
+	\
+
+#endif	/* OVS_LIB_DP_PACKET_H_H */
diff --git a/p4c_bm/plugin/ovs/inc/lib/flow.c.h b/p4c_bm/plugin/ovs/inc/lib/flow.c.h
new file mode 100644
index 0000000..bd6b959
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/lib/flow.c.h
@@ -0,0 +1,625 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//::  import math
+//::
+//::  def byte_array_to_int(bytes):
+//::    res = 0
+//::    len_ = len(bytes)
+//::    for i in xrange(len_):
+//::      res += bytes[len_-1-i] << (8 * i)
+//::    #endfor
+//::    return res
+//::  #enddef
+
+#ifndef OVS_LIB_FLOW_C_H
+#define	OVS_LIB_FLOW_C_H 1
+
+/* -- Used in lib/flow.c -- */
+#define OVS_HDR_RESET_ATTRS \
+//::  for header_name in ordered_header_instances_regular:
+    packet->_${header_name}_ofs = UINT16_MAX; \
+    packet->_${header_name}_valid = 0; \
+//::  #endfor
+    \
+
+/* -- Used in lib/flow.c -- */
+#define OVS_MINIFLOW_EXTRACT_METADATA_DEFS \
+//::  for header_name in ordered_header_instances_metadata:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    struct _${header_name}_padded_header _${header_name} = {{0},{0}}; \
+    bool is__${header_name}_header_touched = false; \
+    \
+//::  #endfor
+    struct valid_padded_header valid = {{0},{0}}; \
+    \
+
+/* -- Used in lib/flow.c -- */
+#define OVS_MINIFLOW_EXTRACT \
+    { \
+        OVS_MINIFLOW__START \
+    } \
+    \
+
+//::  for state, parse_info in parse_states.items():
+#define OVS_MINIFLOW__${state.upper()} \
+//::    # a) Handle call sequence ###
+//::    call_id = 0
+//::    for call in parse_info["call_sequence"]:
+//::      type = call[0]
+//::      if type == "extract":
+//::        header_name = call[1]
+    if (OVS_UNLIKELY(size < sizeof(struct _${header_name}_header))) \
+    { \
+        OVS_MINIFLOW_OUT \
+    } \
+    \
+    packet->_${header_name}_ofs = ((char *) data) - l2; \
+    struct _${header_name}_padded_header *_${header_name} = (struct _${header_name}_padded_header *) data_pull(&data, &size, \
+        sizeof(struct _${header_name}_header)); \
+//::        # TODO: offset increase should be based on header length expression. This needs to be implemented.
+    miniflow_push_bytes__word_aligned_64(mf, _${header_name}, _${header_name}, sizeof(struct _${header_name}_header), \
+        sizeof(struct _${header_name}_padded_header) / sizeof(uint64_t)); \
+	valid.hdr._${header_name}_valid = 1; \
+    \
+//::      elif type == "set":
+//::        destination = call[1]
+//::        metadata_name = field_info[destination]["parent_header"]
+//::        aligned_metadata_name = aligned_field_info[destination]["name"]
+//::        aligned_metadata_mask = aligned_field_info[destination]["mask"]
+//::        aligned_metadata_bit_offset_hdr = aligned_field_info[destination]["bit_offset_hdr"]
+//::        aligned_metadata_bit_width = aligned_field_info[destination]["bit_width"]
+//::        source_type = call[2]
+//::        if source_type == "immediate":
+//::          source_value = hex(byte_array_to_int(call[3]))
+//::          if aligned_metadata_mask:
+//::            if aligned_metadata_bit_width == 8:
+    _${metadata_name}.hdr.${aligned_metadata_name} = ((uint8_t) ${source_value}) << ${aligned_metadata_bit_offset_hdr} \
+        | (_${metadata_name}.hdr.${aligned_metadata_name} & ~${hex(aligned_metadata_mask)}); \
+//::            elif aligned_metadata_bit_width == 16:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htons(((uint16_t) ${source_value}) << ${aligned_metadata_bit_offset_hdr}) \
+        | (_${metadata_name}.hdr.${aligned_metadata_name} & ~htons(${hex(aligned_metadata_mask)})); \
+//::            elif aligned_metadata_bit_width == 32:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htonl(((uint32_t) ${source_value}) << ${aligned_metadata_bit_offset_hdr}) \
+        | (_${metadata_name}.hdr.${aligned_metadata_name} & ~htonl(${hex(aligned_metadata_mask)})); \
+//::            elif aligned_metadata_bit_width == 64:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htonll(((uint64_t) ${source_value}) << ${aligned_metadata_bit_offset_hdr}) \
+        | (_${metadata_name}.hdr.${aligned_metadata_name} & ~htonll(${hex(aligned_metadata_mask)})); \
+//::            else:
+//::              assert(False)  # TODO: handle this case (for arbitrary byte combinations).
+//::            #endif
+//::          else:
+//::            if aligned_metadata_bit_width == 8:
+    _${metadata_name}.hdr.${aligned_metadata_name} = (uint8_t) ${source_value}; \
+//::            elif aligned_metadata_bit_width == 16:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htons((uint16_t) ${source_value}); \
+//::            elif aligned_metadata_bit_width == 32:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htonl((uint32_t) ${source_value}); \
+//::            elif aligned_metadata_bit_width == 64:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htonll((uint64_t) ${source_value}); \
+//::            else:
+//::              assert(False)  # TODO: handle this case (for arbitrary byte combinations).
+//::            #endif
+//::          #endif
+//::        elif source_type == "latest":
+//::          source = call[3]
+//::          header_name = field_info[source]["parent_header"]
+//::          aligned_field_name = aligned_field_info[source]["name"]
+//::          aligned_field_mask = aligned_field_info[source]["mask"]
+//::          aligned_field_bit_offset_hdr = aligned_field_info[source]["bit_offset_hdr"]
+//::          aligned_field_bit_width = aligned_field_info[source]["bit_width"]
+//::          # NOTE: P4 specification assumes that the referenced source header in set_metadata() is already extracted
+//::          # at this point.
+//::          if header_name in ordered_header_instances_regular:
+//::            if aligned_field_mask:
+//::              if aligned_field_bit_width == 8:
+    uint8_t value_${call_id} = (_${header_name}->hdr.${aligned_field_name} & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}; \
+//::              elif aligned_field_bit_width == 16:
+    uint16_t value_${call_id} = (ntohs(_${header_name}->hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}; \
+//::              elif aligned_field_bit_width == 32:
+    uint32_t value_${call_id} = (ntohl(_${header_name}->hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}; \
+//::              elif aligned_field_bit_width == 64:
+    uint64_t value_${call_id} = (ntohll(_${header_name}->hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}; \
+//::              else:
+//::                assert(False)  # TODO: handle this case (for arbitrary byte combinations).
+//::              #endif
+//::            else:
+//::              if aligned_field_bit_width == 8:
+    uint8_t value_${call_id} = _${header_name}->hdr.${aligned_field_name}; \
+//::              elif aligned_field_bit_width == 16:
+    uint16_t value_${call_id} = ntohs(_${header_name}->hdr.${aligned_field_name}); \
+//::              elif aligned_field_bit_width == 32:
+    uint32_t value_${call_id} = ntohl(_${header_name}->hdr.${aligned_field_name}); \
+//::              elif aligned_field_bit_width == 64:
+    uint64_t value_${call_id} = ntohll(_${header_name}->hdr.${aligned_field_name}); \
+//::              else:
+//::                assert(False)  # TODO: handle this case (for arbitrary byte combinations).
+//::              #endif
+//::            #endif
+//::          elif header_name in ordered_header_instances_metadata:
+//::            if aligned_field_mask:
+//::              if aligned_field_bit_width == 8:
+    uint8_t value_${call_id} = (_${metadata_name}.hdr.${aligned_field_name} & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}; \
+//::              elif aligned_field_bit_width == 16:
+    uint16_t value_${call_id} = (ntohs(_${metadata_name}.hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}; \
+//::              elif aligned_field_bit_width == 32:
+    uint32_t value_${call_id} = (nothl(_${metadata_name}.hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}; \
+//::              elif aligned_field_bit_width == 64:
+    uint64_t value_${call_id} = (ntohll(_${metadata_name}.hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}; \
+//::              else:
+//::                assert(False)  # TODO: handle this case (for arbitrary byte combinations).
+//::              #endif
+//::            else:
+//::              if aligned_field_bit_width == 8:
+    uint8_t value_${call_id} = _${metadata_name}.hdr.${aligned_field_name}; \
+//::              elif aligned_field_bit_width == 16:
+    uint16_t value_${call_id} = ntohs(_${metadata_name}.hdr.${aligned_field_name}); \
+//::              elif aligned_field_bit_width == 32:
+    uint32_t value_${call_id} = ntohl(_${metadata_name}.hdr.${aligned_field_name}); \
+//::              elif aligned_field_bit_width == 64:
+    uint64_t value_${call_id} = ntohll(_${metadata_name}.hdr.${aligned_field_name}); \
+//::              else:
+//::                assert(False)  # TODO: handle this case (for arbitrary byte combinations).
+//::              #endif
+//::            #endif
+//::          else:
+//::            assert(False)
+//::          #endif
+//::          if aligned_metadata_mask:
+//::            if aligned_metadata_bit_width == 8:
+    _${metadata_name}.hdr.${aligned_metadata_name} = ((uint8_t) value_${call_id}) << ${aligned_metadata_bit_offset_hdr} \
+        | (_${metadata_name}.hdr.${aligned_metadata_name} & ~${hex(aligned_metadata_mask)}); \
+//::            elif aligned_metadata_bit_width == 16:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htons(((uint16_t) value_${call_id}) << ${aligned_metadata_bit_offset_hdr}) \
+        | (_${metadata_name}.hdr.${aligned_metadata_name} & ~htons(${hex(aligned_metadata_mask)})); \
+//::            elif aligned_metadata_bit_width == 32:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htonl((uint32_t) value_${call_id}) << ${aligned_metadata_bit_offset_hdr}) \
+        | (_${metadata_name}.hdr.${aligned_metadata_name} & ~htonl(${hex(aligned_metadata_mask)})); \
+//::            elif aligned_metadata_bit_width == 64:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htonll((uint64_t) value_${call_id}) << ${aligned_metadata_bit_offset_hdr}) \
+        | (_${metadata_name}.hdr.${aligned_metadata_name} & ~htonll(${hex(aligned_metadata_mask)})); \
+//::            else:
+//::              assert(False)  # TODO: handle this case (for arbitrary byte combinations).
+//::            #endif
+//::          else:
+//::            if aligned_metadata_bit_width == 8:
+    _${metadata_name}.hdr.${aligned_metadata_name} = (uint8_t) value_${call_id}; \
+//::            elif aligned_metadata_bit_width == 16:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htons((uint16_t) value_${call_id}); \
+//::            elif aligned_metadata_bit_width == 32:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htonl((uint32_t) value_${call_id}); \
+//::            elif aligned_metadata_bit_width == 64:
+    _${metadata_name}.hdr.${aligned_metadata_name} = htonll((uint64_t) value_${call_id}); \
+//::            else:
+//::              assert(False)  # TODO: handle this case (for arbitrary byte combinations).
+//::            #endif
+//::          #endif
+//::        else:
+//::          assert(False)  # TODO: handle this case (e.g., current() etc).
+//::        #endif
+    is__${metadata_name}_header_touched = true; \
+    \
+//::      else:
+//::        assert(False)
+//::      #endif
+//::      call_id += 1
+//::    #endfor
+//::    # b) Handle state transitions ###
+//::    branch_on = parse_info['branch_on']
+//::    branch_to = parse_info['branch_to']
+//::    case_id = 0
+//::    for case in branch_to:
+//::      case_type, case_value, case_mask, case_next_state = case
+//::      if case_type == "value":
+//::        branch_id = 0
+//::        key_id = 0
+//::        for key_type, key_value in branch_on:
+//::          if key_type == "field_ref":
+//::            header_name = field_info[key_value]["parent_header"]
+//::            aligned_field_name = aligned_field_info[key_value]["name"]
+//::            aligned_field_bit_width = aligned_field_info[key_value]["bit_width"]
+//::            aligned_field_mask = aligned_field_info[key_value]["mask"]
+//::            aligned_field_bit_offset_hdr = aligned_field_info[key_value]["bit_offset_hdr"]
+//::            if header_name in ordered_header_instances_regular:
+//::              if aligned_field_bit_width == 8:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((_${header_name}->hdr.${aligned_field_name} & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (_${header_name}->hdr.${aligned_field_name} == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 16:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((ntohs(_${header_name}->hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohs(_${header_name}->hdr.${aligned_field_name}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 32:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((ntohl(_${header_name}->hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohl(_${header_name}->hdr.${aligned_field_name}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 64:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((nothll(_${header_name}->hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+8]))}); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohll(_${header_name}->hdr.${field_name}) == ${hex(byte_array_to_int(case_value[key_id:key_id+8]))}); \
+//::                #endif
+//::                key_id += 8
+//::              elif aligned_field_bit_width <= 64:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = false; \
+    { \
+        uint64_t temp = 0; \
+//::                  for i in range(aligned_field_bit_width/8):
+        temp |= ((const uint8_t *) &_${header_name}->hdr.${aligned_field_name})[${i}]; temp <<= (${aligned_field_bit_width} - (8 * (${i} + 1))); \
+//::                  #endfor
+        check_${case_id}_${branch_id} = ((temp & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr} == ${hex(byte_array_to_int(case_value[key_id:key_id+(aligned_field_bit_width/8)]))}); \
+    } \
+//::                else:
+    bool check_${case_id}_${branch_id} = false; \
+    { \
+        uint64_t temp = 0; \
+//::                  for i in range(aligned_field_bit_width/8):
+        temp |= ((const uint8_t *) &_${header_name}->hdr.${aligned_field_name})[${i}]; temp <<= (${aligned_field_bit_width} - (8 * (${i} + 1))); \
+//::                  #endfor
+        check_${case_id}_${branch_id} = (temp == ${hex(byte_array_to_int(case_value[key_id:key_id+(aligned_field_bit_width/8)]))}); \
+    } \
+//::                #endif
+//::                key_id += aligned_field_bit_width/8
+//::              else:
+//::                assert(False)  # TODO: right now only covers up to 64 bits, look into how to extend this range.
+//::              #endif
+//::            elif header_name in ordered_header_instances_metadata:
+//::              if aligned_field_bit_width == 8:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((_${header_name}.hdr.${aligned_field_name} & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (_${header_name}.hdr.${aligned_field_name} == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 16:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((ntohs(_${header_name}.hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohs(_${header_name}.hdr.${aligned_field_name}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 32:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((ntohl(_${header_name}.hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohl(_${header_name}.hdr.${aligned_field_name}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 64:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((nothll(_${header_name}.hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+8]))}); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohll(_${header_name}.hdr.${aligned_field_name}) == ${hex(byte_array_to_int(case_value[key_id:key_id+8]))}); \
+//::                #endif
+//::                key_id += 8
+//::              elif aligned_field_bit_width <= 64:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = false; \
+    { \
+        uint64_t temp = 0; \
+//::                  for i in range(aligned_field_bit_width/8):
+        temp |= ((const uint8_t *) &_${header_name}.hdr.${aligned_field_name})[${i}]; temp <<= (${aligned_field_bit_width} - (8 * (${i} + 1))); \
+//::                  #endfor
+        check_${case_id}_${branch_id} = (temp & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr} == ${hex(byte_array_to_int(case_value[key_id:key_id+(aligned_field_bit_width/8)]))}); \
+    } \
+//::                else:
+    bool check_${case_id}_${branch_id} = false; \
+    { \
+        uint64_t temp = 0; \
+//::                  for i in range(aligned_field_bit_width/8):
+        temp |= ((const uint8_t *) &_${header_name}.hdr.${aligned_field_name})[${i}]; temp <<= (${aligned_field_bit_width} - (8 * (${i} + 1))); \
+//::                  #endfor
+        check_${case_id}_${branch_id} = (temp == ${hex(byte_array_to_int(case_value[key_id:key_id+(aligned_field_bit_width/8)]))}); \
+    } \
+//::                #endif
+//::                key_id += aligned_field_bit_width/8
+//::              else:
+//::                assert(False)  # TODO: right now only covers up to 64 bits, look into how to extend this range.
+//::              #endif
+//::            #endif
+//::          elif key_type == "current":
+//::            key_bit_offset, key_bit_width = key_value
+//::            aligned_key_bit_base_offset = int(key_bit_offset/8)*8
+//::            adjusted_key_bit_offset = key_bit_offset - aligned_key_bit_base_offset
+//::            aligned_key_bit_width = int(math.ceil((adjusted_key_bit_offset+key_bit_width)/8.0)*8)
+//::            aligned_key_bit_offset_hdr = aligned_key_bit_width - ((adjusted_key_bit_offset%aligned_key_bit_width) + key_bit_width)
+//::            aligned_key_mask = ((1 << key_bit_width) - 1) << aligned_key_bit_offset_hdr
+//::            aligned_key_mask = 0 if (((1 << aligned_key_bit_width) - 1) == aligned_key_mask) else aligned_key_mask
+    if (OVS_UNLIKELY(size < (${aligned_key_bit_base_offset/8}+${aligned_key_bit_width/8}))) { OVS_MINIFLOW_OUT } \
+//::            if aligned_key_bit_width == 8:
+//::              if aligned_key_mask:
+    bool check_${case_id}_${branch_id} = ((((*(uint8_t *) (((char *) data) + ${aligned_key_bit_base_offset/8})) & ${hex(aligned_key_mask)}) >> ${aligned_key_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::              else:
+    bool check_${case_id}_${branch_id} = ((*(uint8_t *) (((char *) data) + ${aligned_key_bit_base_offset/8})) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::              #endif
+//::              key_id += 4
+//::            elif aligned_key_bit_width == 16:
+//::              if aligned_key_mask:
+    bool check_${case_id}_${branch_id} = (((ntohs((*(ovs_be16 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) & ${hex(aligned_key_mask)}) >> ${aligned_key_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::              else:
+    bool check_${case_id}_${branch_id} = (ntohs((*(ovs_be16 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::              #endif
+//::              key_id += 4
+//::            elif aligned_key_bit_width == 32:
+//::              if aligned_key_mask:
+    bool check_${case_id}_${branch_id} = (((ntohl((*(ovs_be32 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) & ${hex(aligned_key_mask)}) >> ${aligned_key_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::              else:
+    bool check_${case_id}_${branch_id} = (ntohl((*(ovs_be32 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) == ${hex(byte_array_to_int(case_value[key_id:key_id+4]))}); \
+//::              #endif
+//::              key_id += 4
+//::            elif aligned_key_bit_width == 64:
+//::              if aligned_key_mask:
+    bool check_${case_id}_${branch_id} = (((ntohl((*(ovs_be64 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) & ${hex(aligned_key_mask)}) >> ${aligned_key_bit_offset_hdr}) == ${hex(byte_array_to_int(case_value[key_id:key_id+8]))}); \
+//::              else:
+    bool check_${case_id}_${branch_id} = (ntohl((*(ovs_be64 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) == ${hex(byte_array_to_int(case_value[key_id:key_id+8]))}); \
+//::              #endif
+//::              key_id += 8
+//::            else:
+//::              assert(False)  # TODO: right now only covers up to 64 bits, look into how to extend this range.
+//::            #endif
+//::          else:
+//::            assert(False)
+//::          #endif
+//::          branch_id += 1
+//::        #endfor
+    if ( \
+//::        branch_id = 0
+//::        for key_type, key_value in branch_on:
+        check_${case_id}_${branch_id} && \
+//::          branch_id += 1
+//::        #endfor
+        true) \
+//::      elif case_type == "value_masked":
+//::        branch_id = 0
+//::        key_id = 0
+//::        for key_type, key_value in branch_on:
+//::          if key_type == "field_ref":
+//::            header_name = field_info[key_value]["parent_header"]
+//::            aligned_field_name = aligned_field_info[key_value]["name"]
+//::            aligned_field_bit_width = aligned_field_info[key_value]["bit_width"]
+//::            aligned_field_mask = aligned_field_info[key_value]["mask"]
+//::            aligned_field_bit_offset_hdr = aligned_field_info[key_value]["bit_offset_hdr"]
+//::            if header_name in ordered_header_instances_regular:
+//::              if aligned_field_bit_width == 8:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((_${header_name}->hdr.${aligned_field_name} & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (_${header_name}->hdr.${aligned_field_name} == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 16:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((ntohs(_${header_name}->hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohs(_${header_name}->hdr.${aligned_field_name}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 32:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((ntohl(_${header_name}->hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohl(_${header_name}->hdr.${aligned_field_name}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 64:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((nothll(_${header_name}->hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+8]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+8]))})); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohll(_${header_name}->hdr.${field_name}) == (${hex(byte_array_to_int(case_value[key_id:key_id+8]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+8]))})); \
+//::                #endif
+//::                key_id += 8
+//::              elif aligned_field_bit_width <= 64:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = false; \
+    { \
+        uint64_t temp = 0; \
+//::                  for i in range(aligned_field_bit_width/8):
+        temp |= ((const uint8_t *) &_${header_name}->hdr.${aligned_field_name})[${i}]; temp <<= (${aligned_field_bit_width} - (8 * (${i} + 1))); \
+//::                  #endfor
+        check_${case_id}_${branch_id} = ((temp & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr} == (${hex(byte_array_to_int(case_value[key_id:key_id+(aligned_field_bit_width/8)]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+(aligned_field_bit_width/8)]))})); \
+    } \
+//::                else:
+    bool check_${case_id}_${branch_id} = false; \
+    { \
+        uint64_t temp = 0; \
+//::                  for i in range(aligned_field_bit_width/8):
+        temp |= ((const uint8_t *) &_${header_name}->hdr.${aligned_field_name})[${i}]; temp <<= (${aligned_field_bit_width} - (8 * (${i} + 1))); \
+//::                  #endfor
+        check_${case_id}_${branch_id} = (temp == (${hex(byte_array_to_int(case_value[key_id:key_id+(aligned_field_bit_width/8)]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+(aligned_field_bit_width/8)]))})); \
+    } \
+//::                #endif
+//::                key_id += aligned_field_bit_width/8
+//::              else:
+//::                assert(False)  # TODO: right now only covers up to 64 bits, look into how to extend this range.
+//::              #endif
+//::            elif header_name in ordered_header_instances_metadata:
+//::              if aligned_field_bit_width == 8:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((_${header_name}.hdr.${aligned_field_name} & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (_${header_name}.hdr.${aligned_field_name} == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 16:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((ntohs(_${header_name}.hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohs(_${header_name}.hdr.${aligned_field_name}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 32:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((ntohl(_${header_name}.hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohl(_${header_name}.hdr.${aligned_field_name}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::                #endif
+//::                key_id += 4
+//::              elif aligned_field_bit_width == 64:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = (((nothll(_${header_name}.hdr.${aligned_field_name}) & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+8]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+8]))})); \
+//::                else:
+    bool check_${case_id}_${branch_id} = (ntohll(_${header_name}.hdr.${aligned_field_name}) == (${hex(byte_array_to_int(case_value[key_id:key_id+8]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+8]))})); \
+//::                #endif
+//::                key_id += 8
+//::              elif aligned_field_bit_width <= 64:
+//::                if aligned_field_mask:
+    bool check_${case_id}_${branch_id} = false; \
+    { \
+        uint64_t temp = 0; \
+//::                  for i in range(aligned_field_bit_width/8):
+        temp |= ((const uint8_t *) &_${header_name}.hdr.${aligned_field_name})[${i}]; temp <<= (${aligned_field_bit_width} - (8 * (${i} + 1))); \
+//::                  #endfor
+        check_${case_id}_${branch_id} = ((temp & ${hex(aligned_field_mask)}) >> ${aligned_field_bit_offset_hdr} == (${hex(byte_array_to_int(case_value[key_id:key_id+(aligned_field_bit_width/8)]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+(aligned_field_bit_width/8)]))})); \
+    } \
+//::                else:
+    bool check_${case_id}_${branch_id} = false; \
+    { \
+        uint64_t temp = 0; \
+//::                  for i in range(aligned_field_bit_width/8):
+        temp |= ((const uint8_t *) &_${header_name}.hdr.${aligned_field_name})[${i}]; temp <<= (${aligned_field_bit_width} - (8 * (${i} + 1))); \
+//::                  #endfor
+        check_${case_id}_${branch_id} = (temp == (${hex(byte_array_to_int(case_value[key_id:key_id+(aligned_field_bit_width/8)]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+(aligned_field_bit_width/8)]))})); \
+    } \
+//::                #endif
+//::                key_id += aligned_field_bit_width/8
+//::              else:
+//::                assert(False)  # TODO: right now only covers up to 64 bits, look into how to extend this range.
+//::              #endif
+//::            #endif
+//::          elif key_type == "current":
+//::            key_bit_offset, key_bit_width = key_value
+//::            aligned_key_bit_base_offset = int(key_bit_offset/8)*8
+//::            adjusted_key_bit_offset = key_bit_offset - aligned_key_bit_base_offset
+//::            aligned_key_bit_width = int(math.ceil((adjusted_key_bit_offset+key_bit_width)/8.0)*8)
+//::            aligned_key_bit_offset_hdr = aligned_key_bit_width - ((adjusted_key_bit_offset%aligned_key_bit_width) + key_bit_width)
+//::            aligned_key_mask = ((1 << key_bit_width) - 1) << aligned_key_bit_offset_hdr
+//::            aligned_key_mask = 0 if (((1 << aligned_key_bit_width) - 1) == aligned_key_mask) else aligned_key_mask
+    if (OVS_UNLIKELY(size < (${aligned_key_bit_base_offset/8}+${aligned_key_bit_width/8}))) { OVS_MINIFLOW_OUT } \
+//::            if aligned_key_bit_width == 8:
+//::              if aligned_key_mask:
+    bool check_${case_id}_${branch_id} = ((((*(uint8_t *) (((char *) data) + ${aligned_key_bit_base_offset/8})) & ${hex(aligned_key_mask)}) >> ${aligned_key_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::              else:
+    bool check_${case_id}_${branch_id} = ((*(uint8_t *) (((char *) data) + ${aligned_key_bit_base_offset/8})) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::              #endif
+//::              key_id += 4
+//::            elif aligned_key_bit_width == 16:
+//::              if aligned_key_mask:
+    bool check_${case_id}_${branch_id} = (((ntohs((*(ovs_be16 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) & ${hex(aligned_key_mask)}) >> ${aligned_key_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::              else:
+    bool check_${case_id}_${branch_id} = (ntohs((*(ovs_be16 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::              #endif
+//::              key_id += 4
+//::            elif aligned_key_bit_width == 32:
+//::              if aligned_key_mask:
+    bool check_${case_id}_${branch_id} = (((ntohl((*(ovs_be32 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) & ${hex(aligned_key_mask)}) >> ${aligned_key_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::              else:
+    bool check_${case_id}_${branch_id} = (ntohl((*(ovs_be32 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) == (${hex(byte_array_to_int(case_value[key_id:key_id+4]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+4]))})); \
+//::              #endif
+//::              key_id += 4
+//::            elif aligned_key_bit_width == 64:
+//::              if aligned_key_mask:
+    bool check_${case_id}_${branch_id} = (((ntohl((*(ovs_be64 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) & ${hex(aligned_key_mask)}) >> ${aligned_key_bit_offset_hdr}) == (${hex(byte_array_to_int(case_value[key_id:key_id+8]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+8]))})); \
+//::              else:
+    bool check_${case_id}_${branch_id} = (ntohl((*(ovs_be64 *) (((char *) data) + ${aligned_key_bit_base_offset/8}))) == (${hex(byte_array_to_int(case_value[key_id:key_id+8]))} & ${hex(byte_array_to_int(case_mask[key_id:key_id+8]))})); \
+//::              #endif
+//::              key_id += 8
+//::            else:
+//::              assert(False)  # TODO: right now only covers up to 64 bits, look into how to extend this range.
+//::            #endif
+//::          else:
+//::            assert(False)
+//::          #endif
+//::          branch_id += 1
+//::        #endfor
+    if ( \
+//::        branch_id = 0
+//::        for key_type, key_value in branch_on:
+        check_${case_id}_${branch_id} && \
+//::          branch_id += 1
+//::        #endfor
+        true) \
+//::      elif case_type == "default":
+//::        pass
+//::      else:
+//::        assert(False)
+//::      #endif
+    { \
+//::      if case_next_state[0] == "parse_state":
+        OVS_MINIFLOW__${case_next_state[1].upper()} \
+//::      elif case_next_state[0] == "table" or case_next_state[0] == "conditional_table":
+        OVS_MINIFLOW_OUT \
+//::      else:
+//::        assert(False)
+//::      #endif
+    } \
+    \
+//::      case_id += 1
+//::    #endfor
+
+//::  #endfor
+#define OVS_MINIFLOW_OUT \
+//::  for header_name in ordered_header_instances_metadata:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    if (OVS_LIKELY(is__${header_name}_header_touched)) \
+    { \
+    	miniflow_push_bytes__word_aligned_64(mf, _${header_name}, &_${header_name}, sizeof(struct _${header_name}_header), \
+            sizeof(struct _${header_name}_padded_header) / sizeof(uint64_t)); \
+    } \
+//::  #endfor
+    \
+	miniflow_push_bytes__word_aligned_64(mf, valid, &valid, sizeof(struct valid_header), \
+            sizeof(struct valid_padded_header) / sizeof(uint64_t)); \
+    goto out_; \
+    \
+
+/* -- Used in lib/flow.c -- */
+#define OVS_FLOW_WC_MASK \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::   if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::     continue
+//::   #endif
+    WC_MASK_FIELD(wc, _${header_name}); \
+//::  #endfor
+	\
+
+/* -- Used in lib/flow.c -- */
+#define OVS_FLOW_WC_MAP \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::   if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::     continue
+//::   #endif
+    FLOWMAP_SET(map, _${header_name}); \
+//::  #endfor
+    FLOWMAP_SET(map, valid); \
+    \
+
+#endif	/* OVS_LIB_FLOW_C_H */
diff --git a/p4c_bm/plugin/ovs/inc/lib/match.c.h b/p4c_bm/plugin/ovs/inc/lib/match.c.h
new file mode 100644
index 0000000..d3550a6
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/lib/match.c.h
@@ -0,0 +1,58 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_LIB_MATCH_C_H
+#define	OVS_LIB_MATCH_C_H 1
+
+/* -- Used in lib/match.c -- */
+#define OVS_MATCH_FORMAT \
+    \
+
+#define OVS_MATCH_FORMAT_DISABLED \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+//::      if bit_width == 8:
+    format_be8_masked(s, "${field_name}", f->_${header_name}.hdr.${field_name}, \
+                      wc->masks._${header_name}.hdr.${field_name}); \
+//::      elif bit_width == 16:
+    format_be16_masked(s, "${field_name}", f->_${header_name}.hdr.${field_name}, \
+                       wc->masks._${header_name}.hdr.${field_name}); \
+//::      elif bit_width == 32:
+    format_be32_masked(s, "${field_name}", f->_${header_name}.hdr.${field_name}, \
+                       wc->masks._${header_name}.hdr.${field_name}); \
+//::      elif bit_width == 64:
+    format_be64_masked(s, "${field_name}", f->_${header_name}.hdr.${field_name}, \
+                       wc->masks._${header_name}.hdr.${field_name}); \
+//::      else:
+//::        # NOTE: we assume that all fields are, at least, byte aligned.
+    format_bex_masked(s, "${field_name}", \
+                      (const uint8_t *) &f->_${header_name}.hdr.${field_name}, \
+                      (const uint8_t *) &wc->masks._${header_name}.hdr.${field_name}, \
+                      sizeof f->_${header_name}.hdr.${field_name}); \
+//::      #endif
+//::    #endfor
+    \
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    format_be8_masked(s, "${header_name}_valid", f->valid.hdr._${header_name}_valid, \
+                      wc->masks.valid.hdr._${header_name}_valid); \
+//::  #endfor
+    \
+
+#endif	/* OVS_LIB_MATCH_C_H */
diff --git a/p4c_bm/plugin/ovs/inc/lib/meta-flow.c.h b/p4c_bm/plugin/ovs/inc/lib/meta-flow.c.h
new file mode 100644
index 0000000..c795ac6
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/lib/meta-flow.c.h
@@ -0,0 +1,226 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_LIB_META_FLOW_C_H
+#define	OVS_LIB_META_FLOW_C_H 1
+
+/* -- Used in lib/meta-flow.c -- */
+#define OVS_GET_VALUE_CASES \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+    case MFF_${field_name.upper()}: \
+//::      if bit_width == 8:
+        value->u8 = flow->_${header_name}.hdr.${field_name}; \
+//::      elif bit_width == 16:
+        value->be16 = flow->_${header_name}.hdr.${field_name}; \
+//::      elif bit_width == 32:
+        value->be32 = flow->_${header_name}.hdr.${field_name}; \
+//::      elif bit_width == 64:
+        value->be64 = flow->_${header_name}.hdr.${field_name}; \
+//::      else:
+//::        # NOTE: we assume that all fields are, at least, byte aligned.
+        memcpy(value->data, &flow->_${header_name}.hdr.${field_name}, \
+               sizeof flow->_${header_name}.hdr.${field_name}); \
+//::      #endif
+        break; \
+//::    #endfor
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    case MFF_${header_name.upper()}_VALID: \
+        value->u8 = flow->valid.hdr._${header_name}_valid; \
+        break; \
+//::  #endfor
+    \
+
+/* -- Used in lib/meta-flow.c -- */
+#define OVS_IS_VALUE_VALID_CASES \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+    case MFF_${field_name.upper()}: \
+        return true; \
+//::    #endfor
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    case MFF_${header_name.upper()}_VALID: \
+        return true; \
+//::  #endfor
+    \
+
+/* -- Used in lib/meta-flow.c -- */
+#define OVS_IS_ALL_WILD_CASES \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+    case MFF_${field_name.upper()}: \
+//::      if bit_width == 8 or bit_width == 16 or bit_width == 32 or bit_width == 64:
+        return !wc->masks._${header_name}.hdr.${field_name}; \
+//::      else:
+        return is_all_zeros(&wc->masks._${header_name}.hdr.${field_name}, \
+                            sizeof wc->masks._${header_name}.hdr.${field_name}); \
+//::      #endif
+//::    #endfor
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    case MFF_${header_name.upper()}_VALID: \
+        return !wc->masks.valid.hdr._${header_name}_valid; \
+//::  #endfor
+    \
+
+/* -- Used in lib/meta-flow.c -- */
+#define OVS_SET_FLOW_VALUE_CASES \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+    case MFF_${field_name.upper()}: \
+//::      if bit_width == 8:
+        flow->_${header_name}.hdr.${field_name} = value->u8; \
+//::      elif bit_width == 16:
+        flow->_${header_name}.hdr.${field_name} = value->be16; \
+//::      elif bit_width == 32:
+        flow->_${header_name}.hdr.${field_name} = value->be32; \
+//::      elif bit_width == 64:
+        flow->_${header_name}.hdr.${field_name} = value->be64; \
+//::      else:
+//::        # NOTE: we assume that all fields are, at least, byte aligned.
+        memcpy(&flow->_${header_name}.hdr.${field_name}, value->data, \
+               sizeof flow->_${header_name}.hdr.${field_name}); \
+//::      #endif
+        break; \
+//::    #endfor
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    case MFF_${header_name.upper()}_VALID: \
+        flow->valid.hdr._${header_name}_valid = value->u8; \
+        break; \
+//::  #endfor
+    \
+
+/* -- Used in lib/meta-flow.c -- */
+#define OVS_SET_VLAUE_CASES \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+    case MFF_${field_name.upper()}: \
+//::      if bit_width == 8:
+        match->wc.masks._${header_name}.hdr.${field_name} = 0xff; \
+        match->flow._${header_name}.hdr.${field_name} = value->u8; \
+//::      elif bit_width == 16:
+        match->wc.masks._${header_name}.hdr.${field_name} = OVS_BE16_MAX; \
+        match->flow._${header_name}.hdr.${field_name} = value->be16; \
+//::      elif bit_width == 32:
+        match->wc.masks._${header_name}.hdr.${field_name} = OVS_BE32_MAX; \
+        match->flow._${header_name}.hdr.${field_name} = value->be32; \
+//::      elif bit_width == 64:
+        match->wc.masks._${header_name}.hdr.${field_name} = OVS_BE64_MAX; \
+        match->flow._${header_name}.hdr.${field_name} = value->be64; \
+//::      else:
+//::        # NOTE: we assume that all fields are, at least, byte aligned.
+        memset(&match->wc.masks._${header_name}.hdr.${field_name}, 0xff, \
+               sizeof match->wc.masks._${header_name}.hdr.${field_name}); \
+        memcpy(&match->flow._${header_name}.hdr.${field_name}, value->data, \
+               sizeof match->flow._${header_name}.hdr.${field_name}); \
+//::      #endif
+        break; \
+//::    #endfor
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    case MFF_${header_name.upper()}_VALID: \
+        match->wc.masks.valid.hdr._${header_name}_valid = 0xff; \
+        match->flow.valid.hdr._${header_name}_valid = value->u8; \
+        break; \
+//::  #endfor
+    \
+
+/* -- Used in lib/meta-flow.c -- */
+#define OVS_SET_WILD_CASES \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+    case MFF_${field_name.upper()}: \
+//::      if bit_width == 8 or bit_width == 16 or bit_width == 32 or bit_width == 64:
+        match->flow._${header_name}.hdr.${field_name} = 0; \
+        match->wc.masks._${header_name}.hdr.${field_name} = 0; \
+//::      else:
+//::        # NOTE: we assume that all fields are, at least, byte aligned.
+        memset(&match->flow._${header_name}.hdr.${field_name}, 0, \
+               sizeof match->flow._${header_name}.hdr.${field_name}); \
+        memset(&match->wc.masks._${header_name}.hdr.${field_name}, 0, \
+               sizeof match->wc.masks._${header_name}.hdr.${field_name}); \
+//::      #endif
+        break; \
+//::    #endfor
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    case MFF_${header_name.upper()}_VALID: \
+        match->flow.valid.hdr._${header_name}_valid = 0; \
+        match->wc.masks.valid.hdr._${header_name}_valid = 0; \
+        break; \
+//::  #endfor
+    \
+
+/* -- Used in lib/meta-flow.c -- */
+#define OVS_SET_CASES \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+    case MFF_${field_name.upper()}: \
+//::      if bit_width == 8:
+        match->flow._${header_name}.hdr.${field_name} = value->u8 & mask->u8; \
+        match->wc.masks._${header_name}.hdr.${field_name} = mask->u8; \
+//::      elif bit_width == 16:
+        match->flow._${header_name}.hdr.${field_name} = value->be16 & mask->be16; \
+        match->wc.masks._${header_name}.hdr.${field_name} = mask->be16; \
+//::      elif bit_width == 32:
+        match->flow._${header_name}.hdr.${field_name} = value->be32 & mask->be32; \
+        match->wc.masks._${header_name}.hdr.${field_name} = mask->be32; \
+//::      elif bit_width == 64:
+        match->flow._${header_name}.hdr.${field_name} = value->be64 & mask->be64; \
+        match->wc.masks._${header_name}.hdr.${field_name} = mask->be64; \
+//::      else:
+//::        # NOTE: we assume that all fields are, at least, byte aligned.
+        for (size_t i = 0; i < sizeof match->flow._${header_name}.hdr.${field_name}; i++) { \
+            ((uint8_t *) &match->flow._${header_name}.hdr.${field_name})[i] = (value->data)[i] & (mask->data)[i]; \
+            ((uint8_t *) &match->wc.masks._${header_name}.hdr.${field_name})[i] = (mask->data)[i]; \
+        } \
+//::      #endif
+        break; \
+//::    #endfor
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    case MFF_${header_name.upper()}_VALID: \
+        match->flow.valid.hdr._${header_name}_valid = value->u8 & mask->u8; \
+        match->wc.masks.valid.hdr._${header_name}_valid = mask->u8; \
+        break; \
+//::  #endfor
+    \
+
+#endif	/* OVS_LIB_META_FLOW_C_H */
diff --git a/p4c_bm/plugin/ovs/inc/lib/nx-match.c.h b/p4c_bm/plugin/ovs/inc/lib/nx-match.c.h
new file mode 100644
index 0000000..28fb312
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/lib/nx-match.c.h
@@ -0,0 +1,60 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_LIB_NX_MATCH_C_H
+#define	OVS_LIB_NX_MATCH_C_H 1
+
+/* -- Used in lib/nx-match.c -- */
+#define OVS_MATCH_PUT_RAW \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+//::      if bit_width == 8:
+    nxm_put_8m(b, MFF_${field_name.upper()}, oxm, \
+               flow->_${header_name}.hdr.${field_name}, \
+               match->wc.masks._${header_name}.hdr.${field_name}); \
+//::      elif bit_width == 16:
+    nxm_put_16m(b, MFF_${field_name.upper()}, oxm, \
+                flow->_${header_name}.hdr.${field_name}, \
+                match->wc.masks._${header_name}.hdr.${field_name}); \
+//::      elif bit_width == 32:
+    nxm_put_32m(b, MFF_${field_name.upper()}, oxm, \
+                flow->_${header_name}.hdr.${field_name}, \
+                match->wc.masks._${header_name}.hdr.${field_name}); \
+//::      elif bit_width == 64:
+    nxm_put_64m(b, MFF_${field_name.upper()}, oxm, \
+                flow->_${header_name}.hdr.${field_name}, \
+                match->wc.masks._${header_name}.hdr.${field_name}); \
+//::      else:
+//::        # NOTE: we assume that all fields are, at least, byte aligned.
+    nxm_put(b, MFF_${field_name.upper()}, oxm, \
+            &flow->_${header_name}.hdr.${field_name}, \
+            &match->wc.masks._${header_name}.hdr.${field_name}, \
+            sizeof flow->_${header_name}.hdr.${field_name}); \
+//::      #endif
+//::    #endfor
+    \
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    nxm_put_8m(b, MFF_${header_name.upper()}_VALID, oxm, \
+               flow->valid.hdr._${header_name}_valid, \
+               match->wc.masks.valid.hdr._${header_name}_valid); \
+//::  #endfor
+    \
+
+#endif	/* OVS_LIB_NX_MATCH_C_H */
diff --git a/p4c_bm/plugin/ovs/inc/lib/odp-execute.c.h b/p4c_bm/plugin/ovs/inc/lib/odp-execute.c.h
new file mode 100644
index 0000000..f501d01
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/lib/odp-execute.c.h
@@ -0,0 +1,130 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_LIB_ODP_EXECUTE_C_H
+#define	OVS_LIB_ODP_EXECUTE_C_H 1
+
+/* -- Used in lib/odp-execute.c -- */
+#define OVS_ODP_SET_ACTION_FUNCS \
+//::  for header_name in ordered_header_instances_regular:
+    static void \
+    odp_set__${header_name}(struct dp_packet *packet, const struct ovs_key__${header_name} *key, \
+            const struct ovs_key__${header_name} *mask) \
+    { \
+        struct _${header_name}_header *_${header_name} = dp_packet_${header_name}(packet); \
+        \
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+//::      if bit_width == 8:
+        uint8_t ${field_name} = key->${field_name} | (_${header_name}->${field_name} & ~mask->${field_name}); \
+//::      elif bit_width == 16:
+        ovs_be16 ${field_name} = key->${field_name} | (_${header_name}->${field_name} & ~mask->${field_name}); \
+//::      elif bit_width == 32:
+        ovs_be32 ${field_name} = key->${field_name} | (_${header_name}->${field_name} & ~mask->${field_name}); \
+//::      elif bit_width == 64:
+        ovs_be64 ${field_name} = key->${field_name} | (_${header_name}->${field_name} & ~mask->${field_name}); \
+//::      else:
+        struct ${field_name}_t ${field_name}; \
+        for (size_t i = 0; i < sizeof(struct ${field_name}_t); i++) { \
+            ((uint8_t *) &${field_name})[i] = ((const uint8_t *) &key->${field_name})[i] | \
+                (((const uint8_t *) &_${header_name}->${field_name})[i] & \
+                ~((const uint8_t *) &mask->${field_name})[i]); \
+        } \
+//::      #endif
+//::    #endfor
+        \
+        packet_set__${header_name}( \
+//::    for field_name, _ in ordered_header_instances_non_virtual_field__name_width[header_name]:
+            ${field_name}, \
+//::    #endfor
+            packet); \
+    } \
+    \
+//::  #endfor
+    static void \
+    odp_set_valid(struct dp_packet *packet, const struct ovs_key_valid *key, \
+                   const struct ovs_key_valid *mask) \
+    { \
+//::  for header_name in ordered_header_instances_regular:
+        uint8_t _${header_name}_valid = key->_${header_name}_valid | (packet->_${header_name}_valid & ~mask->_${header_name}_valid); \
+//::  #endfor
+        \
+        packet_set_valid( \
+//::  for header_name in ordered_header_instances_regular:
+            _${header_name}_valid, \
+//::  #endfor
+            packet); \
+    } \
+    \
+
+/* -- Used in lib/odp-execute.c -- */
+#define OVS_ODP_EXECUTE_SET_ACTION_CASES \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_metadata:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    case OVS_KEY_ATTR__${header_name.upper()}: \
+        break; \
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    case OVS_KEY_ATTR__${header_name.upper()}: \
+    { \
+        const struct ovs_key__${header_name} *_${header_name}_key = \
+            nl_attr_get_unspec(a, sizeof(struct ovs_key__${header_name})); \
+        packet_set__${header_name}( \
+//::    for field_name, _ in ordered_header_instances_non_virtual_field__name_width[header_name]:
+            _${header_name}_key->${field_name}, \
+//::    #endfor
+            packet); \
+        break; \
+    } \
+//::  #endfor
+    case OVS_KEY_ATTR_VALID: \
+    { \
+        const struct ovs_key_valid *valid_key = \
+            nl_attr_get_unspec(a, sizeof(struct ovs_key_valid)); \
+        packet_set_valid( \
+//::  for header_name in ordered_header_instances_regular:
+            valid_key->_${header_name}_valid, \
+//::  #endfor
+            packet); \
+        break; \
+    } \
+    \
+
+/* -- Used in lib/odp-execute.c -- */
+#define OVS_ODP_EXECUTE_MASKED_SET_ACTION_CASES \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_metadata:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    case OVS_KEY_ATTR__${header_name.upper()}: \
+        break; \
+//::  #endfor
+//::  for header_name in ordered_header_instances_regular:
+    case OVS_KEY_ATTR__${header_name.upper()}: \
+        odp_set__${header_name}(packet, nl_attr_get(a), \
+                get_mask(a, struct ovs_key__${header_name})); \
+        break; \
+//::  #endfor
+    case OVS_KEY_ATTR_VALID: \
+        odp_set_valid(packet, nl_attr_get(a), \
+                       get_mask(a, struct ovs_key_valid)); \
+        break; \
+    \
+
+#endif	/* OVS_LIB_ODP_EXECUTE_C_H */
diff --git a/p4c_bm/plugin/ovs/inc/lib/odp-util.c.h b/p4c_bm/plugin/ovs/inc/lib/odp-util.c.h
new file mode 100644
index 0000000..9760b07
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/lib/odp-util.c.h
@@ -0,0 +1,251 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_LIB_ODP_UTIL_C_H
+#define	OVS_LIB_ODP_UTIL_C_H 1
+
+/* -- Used in lib/odp-util.c -- */
+#define OVS_KEY_ATTRS_TO_STRING_CASES \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    case OVS_KEY_ATTR__${header_name.upper()}: return "${header_name}"; \
+//::  #endfor
+    case OVS_KEY_ATTR_VALID: return "valid"; \
+    \
+
+/* -- Used in lib/odp-util.c -- */
+#define OVS_FORMAT_ODP_KEY_ATTR_CASES \
+
+#define OVS_FORMAT_ODP_KEY_ATTR_CASES_DISABLED \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    case OVS_KEY_ATTR__${header_name.upper()}: { \
+        const struct ovs_key__${header_name} *key = nl_attr_get(a); \
+        const struct ovs_key__${header_name} *mask = ma ? nl_attr_get(ma) : NULL; \
+        \
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+//::      if bit_width == 8:
+        format_u8x(ds, "${field_name}", key->${field_name}, MASK(mask, ${field_name}), verbose); \
+//::      elif bit_width == 16:
+        format_be16x(ds, "${field_name}", key->${field_name}, MASK(mask, ${field_name}), verbose); \
+//::      elif bit_width == 32:
+        format_be32x(ds, "${field_name}", key->${field_name}, MASK(mask, ${field_name}), verbose); \
+//::      elif bit_width == 64:
+        format_be64x(ds, "${field_name}", key->${field_name}, MASK(mask, ${field_name}), verbose); \
+//::      else:
+        format_bex(ds, "${field_name}", (const uint8_t *) &key->${field_name}, \
+                   mask ? (const uint8_t (*)[]) &mask->${field_name} : NULL, \
+                   sizeof(struct ${field_name}_t), verbose); \
+//::      #endif
+//::    #endfor
+        ds_chomp(ds, ','); \
+        break; \
+    } \
+//::  #endfor
+    case OVS_KEY_ATTR_VALID: { \
+        const struct ovs_key_valid *key = nl_attr_get(a); \
+        const struct ovs_key_valid *mask = ma ? nl_attr_get(ma) : NULL; \
+        \
+//::  for header_name in ordered_header_instances_regular:
+        format_u8x(ds, "${header_name}_valid", key->_${header_name}_valid, MASK(mask, _${header_name}_valid), verbose); \
+//::  #endfor
+        ds_chomp(ds, ','); \
+        break; \
+    } \
+    \
+
+/* -- Used in lib/odp-util.c -- */
+#define OVS_SET_FUNC_DECLS \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    static void \
+    get__${header_name}_key(const struct flow *flow, struct ovs_key__${header_name} *_${header_name}); \
+    static void \
+    put__${header_name}_key(const struct ovs_key__${header_name} *_${header_name}, struct flow *flow); \
+    \
+//::  #endfor
+    static void \
+    get_valid_key(const struct flow *flow, struct ovs_key_valid *valid); \
+    static void \
+    put_valid_key(const struct ovs_key_valid *valid, struct flow *flow); \
+    \
+
+/* -- Used in lib/odp-util.c -- */
+#define OVS_SET_FUNC_DEFS \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    static void \
+    get__${header_name}_key(const struct flow *flow, struct ovs_key__${header_name} *_${header_name}) \
+    { \
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+        _${header_name}->${field_name} = flow->_${header_name}.hdr.${field_name}; \
+//::    #endfor
+    } \
+    \
+    static void \
+    put__${header_name}_key(const struct ovs_key__${header_name} *_${header_name}, struct flow *flow) \
+    { \
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+        flow->_${header_name}.hdr.${field_name} = _${header_name}->${field_name}; \
+//::    #endfor
+    } \
+    \
+//::  #endfor
+    static void \
+    get_valid_key(const struct flow *flow, struct ovs_key_valid *valid) \
+    { \
+//::  for header_name in ordered_header_instances_regular:
+        valid->_${header_name}_valid = flow->valid.hdr._${header_name}_valid; \
+//::  #endfor
+    } \
+    \
+    static void \
+    put_valid_key(const struct ovs_key_valid *valid, struct flow *flow) \
+    { \
+//::  for header_name in ordered_header_instances_regular:
+        flow->valid.hdr._${header_name}_valid = valid->_${header_name}_valid; \
+//::  #endfor
+    } \
+    \
+
+/* -- Used in lib/odp-util.c -- */
+#define OVS_COMMIT_ACTION_FUNCS \
+//::  for header_name in ordered_header_instances_regular:
+    static void \
+    commit_set__${header_name}_action(const struct flow *flow, struct flow *base_flow, \
+               struct ofpbuf *odp_actions, \
+               struct flow_wildcards *wc, \
+               bool use_masked) \
+    { \
+        struct ovs_key__${header_name} key, base, mask; \
+        \
+        get__${header_name}_key(flow, &key); \
+        get__${header_name}_key(base_flow, &base); \
+        get__${header_name}_key(&wc->masks, &mask); \
+        \
+        if (commit(OVS_KEY_ATTR__${header_name.upper()}, use_masked, \
+                   &key, &base, &mask, sizeof key, odp_actions)) { \
+            put__${header_name}_key(&base, base_flow); \
+            put__${header_name}_key(&mask, &wc->masks); \
+        } \
+    } \
+    \
+//::  #endfor
+    static void \
+    commit_set_valid_action(const struct flow *flow, struct flow *base_flow, \
+               struct ofpbuf *odp_actions, \
+               struct flow_wildcards *wc, \
+               bool use_masked) \
+    { \
+        struct ovs_key_valid key, base, mask; \
+        \
+        get_valid_key(flow, &key); \
+        get_valid_key(base_flow, &base); \
+        get_valid_key(&wc->masks, &mask); \
+        \
+        if (commit(OVS_KEY_ATTR_VALID, use_masked, \
+                   &key, &base, &mask, sizeof key, odp_actions)) { \
+            put_valid_key(&base, base_flow); \
+            put_valid_key(&mask, &wc->masks); \
+        } \
+    } \
+    \
+
+/* -- Used in lib/odp-util.c -- */
+#define OVS_COMMIT_ODP_ACTIONS_FUNCS \
+//::  for header_name in ordered_header_instances_regular:
+    commit_set__${header_name}_action(flow, base, odp_actions, wc, use_masked); \
+//::  #endfor
+    commit_set_valid_action(flow, base, odp_actions, wc, use_masked); \
+    \
+
+/* -- Used in lib/odp-util.c -- */
+#define OVS_FLOW_KEY_ATTR_LENS \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    [OVS_KEY_ATTR__${header_name.upper()}] = { .len = sizeof(struct ovs_key__${header_name}) }, \
+//::  #endfor
+    [OVS_KEY_ATTR_VALID] = { .len = sizeof(struct ovs_key_valid) }, \
+    \
+
+/* -- Used in lib/odp-util.c -- */
+#define OVS_FLOW_KEY_FROM_FLOW \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    struct ovs_key__${header_name} *_${header_name}; \
+    _${header_name} = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR__${header_name.upper()}, sizeof *_${header_name}); \
+    get__${header_name}_key(data, _${header_name}); \
+    \
+//::  #endfor
+    struct ovs_key_valid *valid; \
+    valid = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_VALID, sizeof *valid); \
+    get_valid_key(data, valid); \
+    \
+
+/* -- Used in lib/odp-util.c -- */
+#define OVS_FLOW_KEY_TO_FLOW \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR__${header_name.upper()})) { \
+        const struct ovs_key__${header_name} *_${header_name}; \
+        \
+        _${header_name} = nl_attr_get(attrs[OVS_KEY_ATTR__${header_name.upper()}]); \
+        put__${header_name}_key(_${header_name}, flow); \
+        if (is_mask) { \
+            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR__${header_name.upper()}; \
+        } \
+    } \
+    if (!is_mask) { \
+        expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR__${header_name.upper()}; \
+    } \
+    \
+//::  #endfor
+    if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_VALID)) { \
+        const struct ovs_key_valid *valid; \
+        \
+        valid = nl_attr_get(attrs[OVS_KEY_ATTR_VALID]); \
+        put_valid_key(valid, flow); \
+        if (is_mask) { \
+            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_VALID; \
+        } \
+    } \
+    if (!is_mask) { \
+        expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_VALID; \
+    } \
+    \
+
+#endif	/* OVS_LIB_ODP_UTIL_C_H */
diff --git a/p4c_bm/plugin/ovs/inc/lib/packets.c.h b/p4c_bm/plugin/ovs/inc/lib/packets.c.h
new file mode 100644
index 0000000..e6dbf67
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/lib/packets.c.h
@@ -0,0 +1,63 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_LIB_PACKETS_C_H
+#define	OVS_LIB_PACKETS_C_H 1
+
+//:: # NOTE: here we can benefit from annotations. For example, we can provide
+//:: # annotations in P4 to specify which fields can be set in the datapath.
+//::
+/* -- Used in lib/packets.c -- */
+#define OVS_HDR_DEFS \
+//::  for header_name in ordered_header_instances_regular:
+    void packet_set__${header_name}( \
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+//::      if bit_width == 8:
+        uint8_t ${field_name}, \
+//::      elif bit_width == 16:
+        ovs_be16 ${field_name}, \
+//::      elif bit_width == 32:
+        ovs_be32 ${field_name}, \
+//::      elif bit_width == 64:
+        ovs_be64 ${field_name}, \
+//::      else:
+        struct ${field_name}_t ${field_name}, \
+//::      #endif
+//::    #endfor
+        struct dp_packet *packet) \
+    { \
+        struct _${header_name}_header *_${header_name} = dp_packet_${header_name}(packet); \
+        \
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+        _${header_name}->${field_name} = ${field_name}; \
+//::    #endfor
+    } \
+    \
+//:: #endfor
+//::
+    void packet_set_valid( \
+//::  for header_name in ordered_header_instances_regular:
+        uint8_t _${header_name}_valid, \
+//::  #endfor
+        struct dp_packet *packet) \
+    { \
+//::  for header_name in ordered_header_instances_regular:
+        packet->_${header_name}_valid = _${header_name}_valid; \
+//::  #endfor
+    } \
+    \
+
+#endif	/* OVS_LIB_PACKETS_C_H */
diff --git a/p4c_bm/plugin/ovs/inc/lib/packets.h.h b/p4c_bm/plugin/ovs/inc/lib/packets.h.h
new file mode 100644
index 0000000..a058baf
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/lib/packets.h.h
@@ -0,0 +1,51 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_LIB_PACKETS_H_H
+#define	OVS_LIB_PACKETS_H_H 1
+
+//:: # NOTE: here we can benefit from annotations. For example, we can provide
+//:: # annotations in P4 to specify which fields can be set in the datapath.
+//::
+/* -- Used in lib/packets.h -- */
+#define OVS_HDR_DECLS \
+//::  for header_name in ordered_header_instances_regular:
+    void packet_set__${header_name}( \
+//::    for field_name, bit_width in ordered_header_instances_non_virtual_field__name_width[header_name]:
+//::      if bit_width == 8:
+        uint8_t ${field_name}, \
+//::      elif bit_width == 16:
+        ovs_be16 ${field_name}, \
+//::      elif bit_width == 32:
+        ovs_be32 ${field_name}, \
+//::      elif bit_width == 64:
+        ovs_be64 ${field_name}, \
+//::      else:
+//::        # NOTE: we assume that all fields are, at least, byte aligned.
+        struct ${field_name}_t ${field_name}, \
+//::      #endif
+//::    #endfor
+        struct dp_packet *packet); \
+    \
+//::  #endfor
+    void packet_set_valid( \
+//::  for header_name in ordered_header_instances_regular:
+        uint8_t _${header_name}_valid, \
+//::  #endfor
+        struct dp_packet *packet); \
+    \
+
+#endif	/* OVS_LIB_PACKETS_H_H */
diff --git a/p4c_bm/plugin/ovs/inc/ofproto/ofproto-dpif-sflow.c.h b/p4c_bm/plugin/ovs/inc/ofproto/ofproto-dpif-sflow.c.h
new file mode 100644
index 0000000..803d4f2
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/ofproto/ofproto-dpif-sflow.c.h
@@ -0,0 +1,34 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_OFPROTO_OFPROTO_DPIF_SFLOW_C_H
+#define	OVS_OFPROTO_OFPROTO_DPIF_SFLOW_C_H 1
+
+/* -- Called in ofproto/ofproto-dpif-sflow.h -- */
+#define OVS_SFLOW_READ_SET_ACTION_CASES \
+//::  # TODO: remove metadata that is not touched in the parser.
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    case OVS_KEY_ATTR__${header_name.upper()}: \
+        break; \
+//::  #endfor
+    case OVS_KEY_ATTR_VALID: \
+        break; \
+    \
+
+#endif	/* OVS_OFPROTO_OFPROTO_DPIF_SFLOW_C_H */
diff --git a/p4c_bm/plugin/ovs/inc/ofproto/ofproto_dpif_sflow.c.h b/p4c_bm/plugin/ovs/inc/ofproto/ofproto_dpif_sflow.c.h
new file mode 100644
index 0000000..558e851
--- /dev/null
+++ b/p4c_bm/plugin/ovs/inc/ofproto/ofproto_dpif_sflow.c.h
@@ -0,0 +1,33 @@ 
+/*
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVS_OFPROTO_OFPROTO_DPIF_SFLOW_C_H
+#define	OVS_OFPROTO_OFPROTO_DPIF_SFLOW_C_H 1
+
+/* -- Called in ofproto/ofproto-dpif-sflow.h -- */
+#define OVS_SFLOW_READ_SET_ACTION_CASES \
+//::  for header_name in ordered_header_instances_non_virtual:
+//::    if header_name == "standard_metadata" or header_name == "intrinsic_metadata":
+//::      continue
+//::    #endif
+    case OVS_KEY_ATTR__${header_name.upper()}: \
+        break; \
+//::  #endfor
+    case OVS_KEY_ATTR_VALID: \
+        break; \
+    \
+
+#endif	/* OVS_OFPROTO_OFPROTO_DPIF_SFLOW_C_H */
diff --git a/p4c_bm/smart.py b/p4c_bm/smart.py
index 41cd7aa..8268511 100644
--- a/p4c_bm/smart.py
+++ b/p4c_bm/smart.py
@@ -1113,6 +1113,79 @@  def render_dict_populate_registers(render_dict, hlir):
         register_info[name] = r_info
     render_dict["register_info"] = register_info

+# @OVS:
+def render_dict_align_fields(render_dict):
+    render_dict['aligned_field_info'] = {}
+    aligned_field_info = render_dict['aligned_field_info']
+
+    field_info = render_dict['field_info']
+    header_info = render_dict['header_info']
+    ordered_header_instances_all = render_dict['ordered_header_instances_all']
+
+    for header_name in ordered_header_instances_all:
+        header = header_info[header_name]
+
+        field_names = []
+        run_bit_width = 0
+        for field_name in header['fields']:
+            bit_width = field_info[field_name]['bit_width']
+
+            run_bit_width += bit_width
+            if run_bit_width % 8 == 0:
+                if field_names:
+                    # NOTE: we are assuming that smaller fields (i.e., less than a byte)
+                    # combine together to align on a byte boundary.
+                    if run_bit_width <= 1024:
+                        field_names += [field_name]
+
+                        cumm_bit_width = sum([field_info[f]['bit_width'] for f in field_names])
+                        trunc_field_names = [f[len(header_name) + 1:] for f in field_names]
+                        aligned_field_name = header_name + '_' + reduce(lambda x, y: x + '_' + y, trunc_field_names)
+
+                        run_bit_width = 0
+                        field_names.reverse()
+                        for field_name in field_names:
+                            bit_width = field_info[field_name]['bit_width']
+                            # TODO: this might break for fields > 64 bits, look into this.
+                            mask = (2 ** bit_width - 1) << run_bit_width
+                            aligned_field_info[field_name] = {"name": aligned_field_name,
+                                                              "bit_width": cumm_bit_width,
+                                                              "mask": mask,
+                                                              "bit_offset_hdr": run_bit_width}
+
+                            run_bit_width += bit_width
+                    else:
+                        assert(False)
+                else:
+                    aligned_field_name = header_name + '_' + field_name[len(header_name) + 1:]
+
+                    aligned_field_info[field_name] = {"name": aligned_field_name,
+                                                      "bit_width": bit_width,
+                                                      "mask": 0,
+                                                      "bit_offset_hdr": 0}
+                run_bit_width = 0
+                field_names = []
+            else:
+                field_names += [field_name]
+
+# @OVS:
+def render_dict_ordered_field_and_header_instances_non_virtual__name_width(render_dict):
+    render_dict["ordered_field_instances_non_virtual__name_width"] = []
+    render_dict["ordered_header_instances_non_virtual_field__name_width"] = {}
+
+    for header_name in render_dict["ordered_header_instances_non_virtual"]:
+        render_dict["ordered_header_instances_non_virtual_field__name_width"][header_name] = []
+        proc_fields = []
+        for field_name in render_dict["header_info"][header_name]["fields"]:
+            bit_width = render_dict["aligned_field_info"][field_name]["bit_width"]
+            field_name = render_dict["aligned_field_info"][field_name]["name"]
+            if field_name in proc_fields:
+                continue
+            proc_fields += [field_name]
+            render_dict["ordered_field_instances_non_virtual__name_width"] += [(field_name, bit_width)]
+            render_dict["ordered_header_instances_non_virtual_field__name_width"][header_name] += [(field_name,
+                                                                                                    bit_width)]
+
 def get_type(byte_width):
     if byte_width == 1:
         return "uint8_t"
@@ -1171,6 +1244,10 @@  def render_dict_create(hlir,
     render_dict_populate_meters(render_dict, hlir)
     render_dict_populate_registers(render_dict, hlir)

+    # @OVS:
+    render_dict_align_fields(render_dict)
+    render_dict_ordered_field_and_header_instances_non_virtual__name_width(render_dict)
+
     if hlir.p4_egress_ptr:
         render_dict["egress_entry_table"] = get_table_name(hlir.p4_egress_ptr)
     else: