Remove P4 language support.
authorDave Marchevsky <davemarchevsky@fb.com>
Fri, 17 Dec 2021 08:59:26 +0000 (03:59 -0500)
committeryonghong-song <ys114321@gmail.com>
Fri, 17 Dec 2021 19:46:20 +0000 (11:46 -0800)
Remove support for compiling P4 programs (see #3682 for explanation).

Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com>
33 files changed:
src/cc/frontends/p4/README.md [deleted file]
src/cc/frontends/p4/compiler/README.txt [deleted file]
src/cc/frontends/p4/compiler/compilationException.py [deleted file]
src/cc/frontends/p4/compiler/ebpfAction.py [deleted file]
src/cc/frontends/p4/compiler/ebpfConditional.py [deleted file]
src/cc/frontends/p4/compiler/ebpfCounter.py [deleted file]
src/cc/frontends/p4/compiler/ebpfDeparser.py [deleted file]
src/cc/frontends/p4/compiler/ebpfInstance.py [deleted file]
src/cc/frontends/p4/compiler/ebpfParser.py [deleted file]
src/cc/frontends/p4/compiler/ebpfProgram.py [deleted file]
src/cc/frontends/p4/compiler/ebpfScalarType.py [deleted file]
src/cc/frontends/p4/compiler/ebpfStructType.py [deleted file]
src/cc/frontends/p4/compiler/ebpfTable.py [deleted file]
src/cc/frontends/p4/compiler/ebpfType.py [deleted file]
src/cc/frontends/p4/compiler/p4toEbpf.py [deleted file]
src/cc/frontends/p4/compiler/programSerializer.py [deleted file]
src/cc/frontends/p4/compiler/target.py [deleted file]
src/cc/frontends/p4/compiler/topoSorting.py [deleted file]
src/cc/frontends/p4/compiler/typeFactory.py [deleted file]
src/cc/frontends/p4/docs/README.md [deleted file]
src/cc/frontends/p4/scope.png [deleted file]
src/cc/frontends/p4/test/README.txt [deleted file]
src/cc/frontends/p4/test/cleanup.sh [deleted file]
src/cc/frontends/p4/test/endToEndTest.py [deleted file]
src/cc/frontends/p4/test/testP4toEbpf.py [deleted file]
src/cc/frontends/p4/test/testoutputs/.empty [deleted file]
src/cc/frontends/p4/test/testprograms/arrayKey.p4 [deleted file]
src/cc/frontends/p4/test/testprograms/basic_routing.p4 [deleted file]
src/cc/frontends/p4/test/testprograms/bitfields.p4 [deleted file]
src/cc/frontends/p4/test/testprograms/compositeArray.p4 [deleted file]
src/cc/frontends/p4/test/testprograms/compositeKey.p4 [deleted file]
src/cc/frontends/p4/test/testprograms/do_nothing.p4 [deleted file]
src/cc/frontends/p4/test/testprograms/simple.p4 [deleted file]

diff --git a/src/cc/frontends/p4/README.md b/src/cc/frontends/p4/README.md
deleted file mode 100644 (file)
index 4c7b50e..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-# Compiling P4 to EBPF
-
-Mihai Budiu - mbudiu@barefootnetworks.com
-
-September 22, 2015
-
-## Abstract
-
-This document describes a prototype compiler that translates programs
-written in the P4 programming languages to eBPF programs.  The
-translation is performed by generating programs written in a subset of
-the C programming language, that are converted to EBPF using the BPF
-Compiler Collection tools.
-
-The compiler code is licensed under an [Apache v2.0 license]
-(http://www.apache.org/licenses/LICENSE-2.0.html).
-
-## Preliminaries
-
-In this section we give a brief overview of P4 and EBPF.  A detailed
-treatment of these topics is outside the scope of this text.
-
-### P4
-
-P4 (http://p4.org) is a domain-specific programming language for
-specifying the behavior of the dataplanes of network-forwarding
-elements.  The name of the programming language comes from the title
-of a paper published in the proceedings of SIGCOMM Computer
-Communications Review in 2014:
-http://www.sigcomm.org/ccr/papers/2014/July/0000000.0000004:
-"Programming Protocol-Independent Packet Processors".
-
-P4 itself is protocol-independent but allows programmers to express a
-rich set of data plane behaviors and protocols. The core P4
-abstractions are:
-
-* Header definitions describe the format (the set of fields and their
-  sizes) of each header within a packet.
-
-* Parse graphs (finite-state machines) describe the permitted header
-  sequences within received packets.
-
-* Tables associate keys to actions. P4 tables generalize traditional
-  forwarding tables; they can be used to implement routing tables,
-  flow lookup tables, access-control lists, etc.
-
-* Actions describe how packet header fields and metadata are manipulated.
-
-* Match-action units stitch together tables and actions, and perform
-  the following sequence of operations:
-
-  * Construct lookup keys from packet fields or computed metadata,
-
-  * Use the constructed lookup key to index into tables, choosing an
-  action to execute,
-  
-  * Finally, execute the selected action.
-
-* Control flow is expressed as an imperative program describing the
-  data-dependent packet processing within a pipeline, including the
-  data-dependent sequence of match-action unit invocations.
-
-P4 programs describe the behavior of network-processing dataplanes.  A
-P4 program is designed to operate in concert with a separate *control
-plane* program.  The control plane is responsible for managing at
-runtime the contents of the P4 tables.  P4 cannot be used to specify
-control-planes; however, a P4 program implicitly specifies the
-interface between the data-plane and the control-plane.
-
-The P4 language is under active development; the current stable
-version is 1.0.2 (see http://p4.org/spec); a reference implementation
-of a compiler and associated tools is freely available using a Apache
-2 open-source license (see http://p4.org/code).
-
-### EBPF
-
-#### Safe code
-
-EBPF is a acronym that stands for Extended Berkeley Packet Filters.
-In essence EBPF is a low-level programming language (similar to
-machine code); EBPF programs are traditionally executed by a virtual
-machine that resides in the Linux kernel.  EBPF programs can be
-inserted and removed from a live kernel using dynamic code
-instrumentation.  The main feature of EBPF programs is their *static
-safety*: prior to execution all EBPF programs have to be validated as
-being safe, and unsafe programs cannot be executed.  A safe program
-provably cannot compromise the machine it is running on:
-
-* it can only access a restricted memory region (on the local stack)
-
-* it can run only for a limited amount of time; during execution it
-  cannot block, sleep or take any locks
-
-* it cannot use any kernel resources with the exception of a limited
-  set of kernel services which have been specifically whitelisted,
-  including operations to manipulate tables (described below)
-
-#### Kernel hooks
-
-EBPF programs are inserted into the kernel using *hooks*.  There are
-several types of hooks available:
-
-* any function entry point in the kernel can act as a hook; attaching
-  an EBPF program to a function `foo()` will cause the EBPF program to
-  execute every time some kernel thread executes `foo()`.
-
-* EBPF programs can also be attached using the Linux Traffic Control
-  (TC) subsystem, in the network packet processing datapath.  Such
-  programs can be used as TC classifiers and actions.
-
-* EBPF programs can also be attached to sockets or network interfaces.
-  In this case they can be used for processing packets that flow
-  through the socket/interface.
-
-EBPF programs can be used for many purposes; the main use cases are
-dynamic tracing and monitoring, and packet processing.  We are mostly
-interested in the latter use case in this document.
-
-#### EBPF Tables
-
-The EBPF runtime exposes a bi-directional kernel-userspace data
-communication channel, called *tables* (also called maps in some EBPF
-documents and code samples).  EBPF tables are essentially key-value
-stores, where keys and values are arbitrary fixed-size bitstrings.
-The key width, value width and table size (maximum number of entries
-that can be stored) are declared statically, at table creation time.
-
-In user-space tables handles are exposed as file descriptors.  Both
-user- and kernel-space programs can manipulate tables, by inserting,
-deleting, looking up, modifying, and enumerating entries in a table.
-
-In kernel space the keys and values are exposed as pointers to the raw
-underlying data stored in the table, whereas in user-space the
-pointers point to copies of the data.
-
-#### Concurrency
-
-An important aspect to understand related to EBPF is the execution
-model.  An EBPF program is triggered by a kernel hook; multiple
-instances of the same kernel hook can be running simultaneously on
-different cores.
-
-Each table however has a single instances across all the cores.  A
-single table may be accessed simultaneously by multiple instances of
-the same EBPF program running as separate kernel threads on different
-cores.  EBPF tables are native kernel objects, and access to the table
-contents is protected using the kernel RCU mechanism.  This makes
-access to table entries safe under concurrent execution; for example,
-the memory associated to a value cannot be accidentally freed while an
-EBPF program holds a pointer to the respective value.  However,
-accessing tables is prone to data races; since EBPF programs cannot
-use locks, some of these races often cannot be avoided.
-
-EBPF and the associated tools are also under active development, and
-new capabilities are added frequently.  The P4 compiler generates code
-that can be compiled using the BPF Compiler Collection (BCC)
-(https://github.com/iovisor/bcc)
-
-## Compiling P4 to EBPF
-
-From the above description it is apparent that the P4 and EBPF
-programming languages have different expressive powers.  However,
-there is a significant overlap in their capabilities, in particular,
-in the domain of network packet processing.  The following image
-illustrates the situation:
-
-![P4 and EBPF overlap in capabilities](scope.png)
-
-We expect that the overlapping region will grow in size as both P4 and
-EBPF continue to mature.
-
-The current version of the P4 to EBPF compiler translates programs
-written in the version 1.1 of the P4 programming language to programs
-written in a restricted subset of C.  The subset of C is chosen such
-that it should be compilable to EBPF using BCC.
-
-```
-         --------------              -------
-P4 --->  | P4-to-EBPF | ---> C ----> | BCC | --> EBPF
-         --------------              -------
-```
-
-The P4 program only describes the packet processing *data plane*, that
-runs in the Linux kernel.  The *control plane* must be separately
-implemented by the user.  The BCC tools simplify this task
-considerably, by generating C and/or Python APIs that expose the
-dataplane/control-plane APIs.
-
-### Dependencies
-
-EBPF programs require a Linux kernel with version 4.2 or newer.
-
-In order to use the P4 to EBPF compiler the following software must be installed:
-
-* The compiler itself is written in the Python (v2.x) programming
-  language.
-
-* the P4 compiler front-end: (https://github.com/p4lang/p4-hlir).
-  This is required for parsing the P4 programs.  
-
-* the BCC compiler collection tools: (https://github.com/iovisor/bcc).
-  This is required for compiling the generated code.  Also, BCC comes
-  with a set of Python utilities which can be used to implement
-  control-plane programs that operate in concert with the kernel EBPF
-  datapath.
-
-The P4 to EBPF compiler generates code that is designed for being used
-as a classifier using the Linux TC subsystem.
-
-Furthermore, the test code provided is written using the Python (v3.x)
-programming language and requires several Python packages to be
-installed.
-
-### Supported capabilities
-
-The current version of the P4 to EBPF compiler supports a relatively
-narrow subset of the P4 language, but still powerful enough to write
-very complex packet filters and simple packet forwarding engines.  In
-the spirit of open-source "release early, release often", we expect
-that the compiler's capabilities will improve gradually.
-
-* Packet filtering is performed using the `drop()` action.  Packets
-  that are not dropped will be forwarded.
-
-* Packet forwarding is performed by setting the
-  `standard_metadata.egress_port` to the index of the destination
-  network interface
-
-Here are some limitations imposed on the P4 programs:
-
-* Currently both the ingress and the egress P4 pipelines are executed
-  at the same hook (wherever the user chooses to insert the generated
-  EBPF program).  In the future the compiler should probably generate
-  two separate EBPF programs.
-
-* arbitrary parsers can be compiled, but the BCC compiler will reject
-  parsers that contain cycles
-
-* arithmetic on data wider than 32 bits is not supported
-
-* checksum computations are not implemented.  In consequence, programs
-  that IP/TCP/UDP headers will produce incorrect packet headers.
-
-* EBPF does not offer support for ternary or LPM tables
-
-* P4 cloning and recirculation and not supported
-
-* meters and registers are not supported; only direct counters are
-  currently supported.  EBPF can potentially support registers and
-  arbitrary counters, so these may appear in the future.
-
-* learning (i.e. `generate_digest`) is not implemented
-
-### Translating P4 to C
-
-To simplify the translation, the P4 programmer should refrain using
-identifiers whose name starts with `ebpf_`.
-
-The following table provides a brief summary of how each P4 construct
-is mapped to a corresponding C construct:
-
-#### Translating parsers
-
-P4 Construct | C Translation
-----------|------------
-`header_type` | `struct` type
-`header`      | `struct` instance with an additional `valid` bit
-`metadata`    | `struct` instance
-parser state  | code block
-state transition | `goto` statement
-`extract` | load/shift/mask data from packet buffer
-
-#### Translating match-action pipelines
-
-P4 Construct | C Translation
-----------|------------
-table  | 2 EBPF tables: second one used just for the default action
-table key | `struct` type
-table `actions` block | tagged `union` with all possible actions
-`action` arguments | `struct`
-table `reads` | EBPF table access
-`action` body | code block
-table `apply` | `switch` statement
-counters | additional EBPF table
-
-### Code organization
-
-The compiler code is organized in two folders:
-
-* `compiler`: the complete compiler source code, in Python v2.x
-  The compiler entry point is `p4toEbpf.py`.
-
-* `test`: testing code and data.  There are two testing programs:
-  * `testP4toEbpf.py`: which compiles all P4 files in the testprograms folder
-
-  * `endToEndTest.py`: which compiles and executes the simple.p4
-  program, and includes a simple control plane
-
-Currently the compiler contains no installation capabilities.
-
-### Invoking the compiler
-
-Invoking the compiler is just a matter of invoking the python program
-with a suitable input P4 file:
-
-```
-p4toEbpf.py file.p4 -o file.c
-```
-
-#### Compiler options
-
-The P4 compiler first runs the C preprocessor on the input P4 file.
-Some of the command-line options are passed directly to the
-preprocessor.
-
-The following compiler options are available:
-
-Option | Meaning
--------|--------
-`-D macro` | Option passed to C preprocessor
-`-I path`  | Option passed to C preprocessor
-`-U macro` | Option passed to C preprocessor
-`-g [router|filter]` | Controls whether the generated code behaves like a router or a filter.
-`-o outoutFile` | writes the generated C code to the specified output file.
-
-The `-g` option controls the nature of the generated code:
-
-* `-g filter` generates a filter; the only P4 action that has an
-  effect is the `drop()` action.  Setting metadata in P4 (e.g.,
-  `egress_port`) has no effect.
-
-* `-g router` generates a simple router; both `drop()` and
-  `egress_port` impact packet processing.
-
-#### Using the generated code
-
-The resulting file contains the complete data structures, tables, and
-a C function named `ebpf_filter` that implements the P4-specified
-data-plane.  This C file can be manipulated using the BCC tools;
-please refer to the BCC project documentation and sample test files of
-the P4 to EBPF source code for an in-depth understanding.  A minimal
-Python program that compiles and loads into the kernel the generated
-file into EBPF is:
-
-```
-#!/usr/bin/env python3
-from bcc import BPF
-
-b = BPF(src_file="file.c", debug=0)
-fn = b.load_func("ebpf_filter", BPF.SCHED_CLS)
-```
-
-##### Connecting the generated program with the TC
-
-The EBPF code that is generated is intended to be used as a classifier
-attached to the ingress packet path using the Linux TC subsystem.  The
-same EBPF code should be attached to all interfaces.  Note however
-that all EBPF code instances share a single set of tables, which are
-used to control the program behavior.
-
-The following code fragment illustrates how the EBPF code can be
-hooked up to the `eth0` interface using a Python program.  (The `fn`
-variable is the one produced by the previous code fragment).
-
-```
-from pyroute2 import IPRoute
-
-ipr = IPRoute()
-interface_name="eth0"
-if_index = ipr.link_lookup(ifname=interface_name)[0]
-ipr.tc("add", "ingress", if_index, "ffff:")
-ipr.tc("add-filter", "bpf", if_index, ":1", fd=fn.fd,
-       name=fn.name, parent="ffff:", action="ok", classid=1)
-```
diff --git a/src/cc/frontends/p4/compiler/README.txt b/src/cc/frontends/p4/compiler/README.txt
deleted file mode 100644 (file)
index c610240..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-This folder contains an implementation of a simple compiler that
-translates a programs written in a subset of P4 into C that can in
-turn be compiled into EBPF using the IOVisor bcc compiler.
-
diff --git a/src/cc/frontends/p4/compiler/compilationException.py b/src/cc/frontends/p4/compiler/compilationException.py
deleted file mode 100644 (file)
index cc0e5ba..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-class CompilationException(Exception):
-    """Signals an error during compilation"""
-    def __init__(self, isBug, format, *message):
-        # isBug: indicates that this is a compiler bug
-        super(CompilationException, self).__init__()
-
-        assert isinstance(format, str)
-        assert isinstance(isBug, bool)
-        self.message = message
-        self.format = format
-        self.isBug = isBug
-
-    def show(self):
-        # TODO: format this message nicely
-        return self.format.format(*self.message)
-
-
-class NotSupportedException(Exception):
-    archError = " not supported by EBPF"
-
-    def __init__(self, format, *message):
-        super(NotSupportedException, self).__init__()
-
-        assert isinstance(format, str)
-        self.message = message
-        self.format = format
-
-    def show(self):
-        # TODO: format this message nicely
-        return (self.format + NotSupportedException.archError).format(
-            *self.message)
diff --git a/src/cc/frontends/p4/compiler/ebpfAction.py b/src/cc/frontends/p4/compiler/ebpfAction.py
deleted file mode 100644 (file)
index 99bf145..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import p4_action, p4_field
-from p4_hlir.hlir import p4_signature_ref, p4_header_instance
-import ebpfProgram
-from programSerializer import ProgramSerializer
-from compilationException import *
-import ebpfScalarType
-import ebpfCounter
-import ebpfType
-import ebpfInstance
-
-
-class EbpfActionData(object):
-    def __init__(self, name, argtype):
-        self.name = name
-        self.argtype = argtype
-
-
-class EbpfActionBase(object):
-    def __init__(self, p4action):
-        self.name = p4action.name
-        self.hliraction = p4action
-        self.builtin = False
-        self.arguments = []
-
-    def serializeArgumentsAsStruct(self, serializer):
-        serializer.emitIndent()
-        serializer.appendFormat("/* no arguments for {0} */", self.name)
-        serializer.newline()
-
-    def serializeBody(self, serializer, valueName, program):
-        serializer.emitIndent()
-        serializer.appendFormat("/* no body for {0} */", self.name)
-        serializer.newline()
-
-    def __str__(self):
-        return "EbpfAction({0})".format(self.name)
-
-
-class EbpfAction(EbpfActionBase):
-    unsupported = [
-        # The following cannot be done in EBPF
-        "add_header", "remove_header", "execute_meter",
-        "clone_ingress_pkt_to_egress",
-        "clone_egress_pkt_to_egress", "generate_digest", "resubmit",
-        "modify_field_with_hash_based_offset", "truncate", "push", "pop",
-        # The following could be done, but are not yet implemented
-        # The situation with copy_header is complicated,
-        # because we don't do checksums
-        "copy_header", "count",
-        "register_read", "register_write"]
-
-    # noinspection PyUnresolvedReferences
-    def __init__(self, p4action, program):
-        super(EbpfAction, self).__init__(p4action)
-        assert isinstance(p4action, p4_action)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        self.builtin = False
-        self.invalid = False  # a leaf action which is never
-                              # called from a table can be invalid.
-
-        for i in range(0, len(p4action.signature)):
-            param = p4action.signature[i]
-            width = p4action.signature_widths[i]
-            if width is None:
-                self.invalid = True
-                return
-            argtype = ebpfScalarType.EbpfScalarType(p4action, width,
-                                                    False, program.config)
-            actionData = EbpfActionData(param, argtype)
-            self.arguments.append(actionData)
-
-    def serializeArgumentsAsStruct(self, serializer):
-        if self.invalid:
-            raise CompilationException(True,
-                "{0} Attempting to generate code for an invalid action",
-                                       self.hliraction)
-
-        # Build a struct containing all action arguments.
-        serializer.emitIndent()
-        serializer.append("struct ")
-        serializer.blockStart()
-        assert isinstance(serializer, ProgramSerializer)
-        for arg in self.arguments:
-            assert isinstance(arg, EbpfActionData)
-            serializer.emitIndent()
-            argtype = arg.argtype
-            assert isinstance(argtype, ebpfType.EbpfType)
-            argtype.declare(serializer, arg.name, False)
-            serializer.endOfStatement(True)
-        serializer.blockEnd(False)
-        serializer.space()
-        serializer.append(self.name)
-        serializer.endOfStatement(True)
-
-    def serializeBody(self, serializer, dataContainer, program):
-        if self.invalid:
-            raise CompilationException(True,
-                "{0} Attempting to generate code for an invalid action",
-                                       self.hliraction)
-
-        # TODO: generate PARALLEL implementation
-        # dataContainer is a string containing the variable name
-        # containing the action data
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-        assert isinstance(dataContainer, str)
-        callee_list = self.hliraction.flat_call_sequence
-        for e in callee_list:
-            action = e[0]
-            assert isinstance(action, p4_action)
-            arguments = e[1]
-            assert isinstance(arguments, list)
-            self.serializeCallee(self, action, arguments, serializer,
-                                 dataContainer, program)
-
-    def checkSize(self, call, args, program):
-        size = None
-        for a in args:
-            if a is None:
-                continue
-            if size is None:
-                size = a
-            elif a != size:
-                program.emitWarning(
-                    "{0}: Arguments do not have the same size {1} and {2}",
-                    call, size, a)
-        return size
-
-    @staticmethod
-    def translateActionToOperator(actionName):
-        if actionName == "add" or actionName == "add_to_field":
-            return "+"
-        elif actionName == "bit_and":
-            return "&"
-        elif actionName == "bit_or":
-            return "|"
-        elif actionName == "bit_xor":
-            return "^"
-        elif actionName == "subtract" or actionName == "subtract_from_field":
-            return "-"
-        else:
-            raise CompilationException(True,
-                                       "Unexpected primitive action {0}",
-                                       actionName)
-
-    def serializeCount(self, caller, arguments, serializer,
-                       dataContainer, program):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-        assert isinstance(arguments, list)
-        assert len(arguments) == 2
-
-        counter = arguments[0]
-        index = ArgInfo(arguments[1], caller, dataContainer, program)
-        ctr = program.getCounter(counter.name)
-        assert isinstance(ctr, ebpfCounter.EbpfCounter)
-        serializer.emitIndent()
-        serializer.blockStart()
-
-        # This is actually incorrect, since the key is not always an u32.
-        # This code is currently disabled
-        key = program.reservedPrefix + "index"
-        serializer.emitIndent()
-        serializer.appendFormat("u32 {0} = {1};", key, index.asString)
-        serializer.newline()
-
-        ctr.serializeCode(key, serializer, program)
-
-        serializer.blockEnd(True)
-
-    def serializeCallee(self, caller, callee, arguments,
-                        serializer, dataContainer, program):
-        if self.invalid:
-            raise CompilationException(
-                True,
-                "{0} Attempting to generate code for an invalid action",
-                self.hliraction)
-
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-        assert isinstance(callee, p4_action)
-        assert isinstance(arguments, list)
-
-        if callee.name in EbpfAction.unsupported:
-            raise NotSupportedException("{0}", callee)
-
-        # This is not yet ready
-        #if callee.name == "count":
-        #    self.serializeCount(caller, arguments,
-        #                        serializer, dataContainer, program)
-        #    return
-
-        serializer.emitIndent()
-        args = self.transformArguments(arguments, caller,
-                                       dataContainer, program)
-        if callee.name == "modify_field":
-            dst = args[0]
-            src = args[1]
-
-            size = self.checkSize(callee,
-                                  [a.widthInBits() for a in args],
-                                  program)
-            if size is None:
-                raise CompilationException(
-                    True, "Cannot infer width for arguments {0}",
-                    callee)
-            elif size <= 32:
-                serializer.appendFormat("{0} = {1};",
-                                        dst.asString,
-                                        src.asString)
-            else:
-                if not dst.isLvalue:
-                    raise NotSupportedException(
-                        "Constants wider than 32-bit: {0}({1})",
-                        dst.caller, dst.asString)
-                if not src.isLvalue:
-                    raise NotSupportedException(
-                        "Constants wider than 32-bit: {0}({1})",
-                        src.caller, src.asString)
-                serializer.appendFormat("memcpy(&{0}, &{1}, {2});",
-                                        dst.asString,
-                                        src.asString,
-                                        size / 8)
-        elif (callee.name == "add" or
-             callee.name == "bit_and" or
-             callee.name == "bit_or" or
-             callee.name == "bit_xor" or
-             callee.name == "subtract"):
-            size = self.checkSize(callee,
-                                  [a.widthInBits() for a in args],
-                                  program)
-            if size is None:
-                raise CompilationException(
-                    True,
-                    "Cannot infer width for arguments {0}",
-                    callee)
-            if size > 32:
-                raise NotSupportedException("{0}: Arithmetic on {1}-bits",
-                                            callee, size)
-            op = EbpfAction.translateActionToOperator(callee.name)
-            serializer.appendFormat("{0} = {1} {2} {3};",
-                                    args[0].asString,
-                                    args[1].asString,
-                                    op,
-                                    args[2].asString)
-        elif (callee.name == "add_to_field" or
-              callee.name == "subtract_from_field"):
-            size = self.checkSize(callee,
-                                  [a.widthInBits() for a in args],
-                                  program)
-            if size is None:
-                raise CompilationException(
-                    True, "Cannot infer width for arguments {0}", callee)
-            if size > 32:
-                raise NotSupportedException(
-                    "{0}: Arithmetic on {1}-bits", callee, size)
-
-            op = EbpfAction.translateActionToOperator(callee.name)
-            serializer.appendFormat("{0} = {0} {1} {2};",
-                                    args[0].asString,
-                                    op,
-                                    args[1].asString)
-        elif callee.name == "no_op":
-            serializer.append("/* noop */")
-        elif callee.name == "drop":
-            serializer.appendFormat("{0} = 1;", program.dropBit)
-        elif callee.name == "push" or callee.name == "pop":
-            raise CompilationException(
-                True, "{0} push/pop not yet implemented", callee)
-        else:
-            raise CompilationException(
-                True, "Unexpected primitive action {0}", callee)
-        serializer.newline()
-
-    def transformArguments(self, arguments, caller, dataContainer, program):
-        result = []
-        for a in arguments:
-            t = ArgInfo(a, caller, dataContainer, program)
-            result.append(t)
-        return result
-
-
-class BuiltinAction(EbpfActionBase):
-    def __init__(self, p4action):
-        super(BuiltinAction, self).__init__(p4action)
-        self.builtin = True
-
-    def serializeBody(self, serializer, valueName, program):
-        # This is ugly; there should be a better way
-        if self.name == "drop":
-            serializer.emitIndent()
-            serializer.appendFormat("{0} = 1;", program.dropBit)
-            serializer.newline()
-        else:
-            serializer.emitIndent()
-            serializer.appendFormat("/* no body for {0} */", self.name)
-            serializer.newline()
-
-
-class ArgInfo(object):
-    # noinspection PyUnresolvedReferences
-    # Represents an argument passed to an action
-    def __init__(self, argument, caller, dataContainer, program):
-        self.width = None
-        self.asString = None
-        self.isLvalue = True
-        self.caller = caller
-
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-        assert isinstance(caller, EbpfAction)
-
-        if isinstance(argument, int):
-            self.asString = str(argument)
-            self.isLvalue = False
-            # size is unknown
-        elif isinstance(argument, p4_field):
-            if ebpfProgram.EbpfProgram.isArrayElementInstance(
-                    argument.instance):
-                if isinstance(argument.instance.index, int):
-                    index = "[" + str(argument.instance.index) + "]"
-                else:
-                    raise CompilationException(
-                        True,
-                        "Unexpected index for array {0}",
-                        argument.instance.index)
-                stackInstance = program.getStackInstance(
-                    argument.instance.base_name)
-                assert isinstance(stackInstance, ebpfInstance.EbpfHeaderStack)
-                fieldtype = stackInstance.basetype.getField(argument.name)
-                self.width = fieldtype.widthInBits()
-                self.asString = "{0}.{1}{3}.{2}".format(
-                    program.headerStructName,
-                    stackInstance.name, argument.name, index)
-            else:
-                instance = program.getInstance(argument.instance.base_name)
-                if isinstance(instance, ebpfInstance.EbpfHeader):
-                    parent = program.headerStructName
-                else:
-                    parent = program.metadataStructName
-                fieldtype = instance.type.getField(argument.name)
-                self.width = fieldtype.widthInBits()
-                self.asString = "{0}.{1}.{2}".format(
-                    parent, instance.name, argument.name)
-        elif isinstance(argument, p4_signature_ref):
-            refarg = caller.arguments[argument.idx]
-            self.asString = "{0}->u.{1}.{2}".format(
-                dataContainer, caller.name, refarg.name)
-            self.width = caller.arguments[argument.idx].argtype.widthInBits()
-        elif isinstance(argument, p4_header_instance):
-            # This could be a header array element
-            # Unfortunately for push and pop, the user mean the whole array,
-            # but the representation contains just the first element here.
-            # This looks like a bug in the HLIR.
-            if ebpfProgram.EbpfProgram.isArrayElementInstance(argument):
-                if isinstance(argument.index, int):
-                    index = "[" + str(argument.index) + "]"
-                else:
-                    raise CompilationException(
-                        True,
-                        "Unexpected index for array {0}", argument.index)
-                stackInstance = program.getStackInstance(argument.base_name)
-                assert isinstance(stackInstance, ebpfInstance.EbpfHeaderStack)
-                fieldtype = stackInstance.basetype
-                self.width = fieldtype.widthInBits()
-                self.asString = "{0}.{1}{2}".format(
-                    program.headerStructName, stackInstance.name, index)
-            else:
-                instance = program.getInstance(argument.name)
-                instancetype = instance.type
-                self.width = instancetype.widthInBits()
-                self.asString = "{0}.{1}".format(
-                    program.headerStructName, argument.name)
-        else:
-            raise CompilationException(
-                True, "Unexpected action argument {0}", argument)
-
-    def widthInBits(self):
-        return self.width
diff --git a/src/cc/frontends/p4/compiler/ebpfConditional.py b/src/cc/frontends/p4/compiler/ebpfConditional.py
deleted file mode 100644 (file)
index 5c723d2..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import p4_conditional_node, p4_expression
-from p4_hlir.hlir import p4_header_instance, p4_field
-from programSerializer import ProgramSerializer
-from compilationException import CompilationException
-import ebpfProgram
-import ebpfInstance
-
-
-class EbpfConditional(object):
-    @staticmethod
-    def translate(op):
-        if op == "not":
-            return "!"
-        elif op == "or":
-            return "||"
-        elif op == "and":
-            return "&&"
-        return op
-
-    def __init__(self, p4conditional, program):
-        assert isinstance(p4conditional, p4_conditional_node)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-        self.hlirconditional = p4conditional
-        self.name = p4conditional.name
-
-    def emitNode(self, node, serializer, program):
-        if isinstance(node, p4_expression):
-            self.emitExpression(node, serializer, program, False)
-        elif node is None:
-            pass
-        elif isinstance(node, int):
-            serializer.append(node)
-        elif isinstance(node, p4_header_instance):
-            header = program.getInstance(node.name)
-            assert isinstance(header, ebpfInstance.EbpfHeader)
-            # TODO: stacks?
-            serializer.appendFormat(
-                "{0}.{1}", program.headerStructName, header.name)
-        elif isinstance(node, p4_field):
-            instance = node.instance
-            einstance = program.getInstance(instance.name)
-            if isinstance(einstance, ebpfInstance.EbpfHeader):
-                base = program.headerStructName
-            else:
-                base = program.metadataStructName
-            serializer.appendFormat(
-                "{0}.{1}.{2}", base, einstance.name, node.name)
-        else:
-            raise CompilationException(True, "{0} Unexpected expression ", node)
-
-    def emitExpression(self, expression, serializer, program, toplevel):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-        assert isinstance(expression, p4_expression)
-        assert isinstance(toplevel, bool)
-        left = expression.left
-        op = expression.op
-        right = expression.right
-
-        assert isinstance(op, str)
-
-        if op == "valid":
-            self.emitNode(right, serializer, program)
-            serializer.append(".valid")
-            return
-
-        if not toplevel:
-            serializer.append("(")
-        self.emitNode(left, serializer, program)
-        op = EbpfConditional.translate(op)
-        serializer.append(op)
-        self.emitNode(right, serializer, program)
-        if not toplevel:
-            serializer.append(")")
-
-    def generateCode(self, serializer, program, nextNode):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-        serializer.emitIndent()
-        serializer.blockStart()
-
-        trueBranch = self.hlirconditional.next_[True]
-        if trueBranch is None:
-            trueBranch = nextNode
-        falseBranch = self.hlirconditional.next_[False]
-        if falseBranch is None:
-            falseBranch = nextNode
-
-        serializer.emitIndent()
-        serializer.appendFormat("{0}:", program.getLabel(self.hlirconditional))
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.append("if (")
-        self.emitExpression(
-            self.hlirconditional.condition, serializer, program, True)
-        serializer.appendLine(")")
-
-        serializer.increaseIndent()
-        label = program.getLabel(trueBranch)
-        serializer.emitIndent()
-        serializer.appendFormat("goto {0};", label)
-        serializer.newline()
-        serializer.decreaseIndent()
-
-        serializer.emitIndent()
-        serializer.appendLine("else")
-        serializer.increaseIndent()
-        label = program.getLabel(falseBranch)
-        serializer.emitIndent()
-        serializer.appendFormat("goto {0};", label)
-        serializer.newline()
-        serializer.decreaseIndent()
-
-        serializer.blockEnd(True)
diff --git a/src/cc/frontends/p4/compiler/ebpfCounter.py b/src/cc/frontends/p4/compiler/ebpfCounter.py
deleted file mode 100644 (file)
index 5b5b396..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import p4_counter, P4_DIRECT, P4_COUNTER_BYTES
-from programSerializer import ProgramSerializer
-from compilationException import *
-import ebpfTable
-import ebpfProgram
-
-
-class EbpfCounter(object):
-    # noinspection PyUnresolvedReferences
-    def __init__(self, hlircounter, program):
-        assert isinstance(hlircounter, p4_counter)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        self.name = hlircounter.name
-        self.hlircounter = hlircounter
-
-        width = hlircounter.min_width
-        # ebpf counters only work on 64-bits
-        if width <= 64:
-            self.valueTypeName = program.config.uprefix + "64"
-        else:
-            raise NotSupportedException(
-                "{0}: Counters with {1} bits", hlircounter, width)
-
-        self.dataMapName = self.name
-
-        if ((hlircounter.binding is None) or
-            (hlircounter.binding[0] != P4_DIRECT)):
-            raise NotSupportedException(
-                "{0}: counter which is not direct", hlircounter)
-
-        self.autoIncrement = (hlircounter.binding != None and
-                              hlircounter.binding[0] == P4_DIRECT)
-
-        if hlircounter.type is P4_COUNTER_BYTES:
-            self.increment = "{0}->len".format(program.packetName)
-        else:
-            self.increment = "1"
-
-    def getSize(self, program):
-        if self.hlircounter.instance_count is not None:
-            return self.hlircounter.instance_count
-        if self.autoIncrement:
-            return self.getTable(program).size
-        program.emitWarning(
-            "{0} does not specify a max_size; using 1024", self.hlircounter)
-        return 1024
-
-    def getTable(self, program):
-        table = program.getTable(self.hlircounter.binding[1].name)
-        assert isinstance(table, ebpfTable.EbpfTable)
-        return table
-
-    def serialize(self, serializer, program):
-        assert isinstance(serializer, ProgramSerializer)
-
-        # Direct counters have the same key as the associated table
-        # Static counters have integer keys
-        if self.autoIncrement:
-            keyTypeName = "struct " + self.getTable(program).keyTypeName
-        else:
-            keyTypeName = program.config.uprefix + "32"
-        program.config.serializeTableDeclaration(
-            serializer, self.dataMapName, True, keyTypeName,
-            self.valueTypeName, self.getSize(program))
-
-    def serializeCode(self, keyname, serializer, program):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        serializer.emitIndent()
-        serializer.appendFormat("/* Update counter {0} */", self.name)
-        serializer.newline()
-
-        valueName = "ctrvalue"
-        initValuename = "init_val"
-
-        serializer.emitIndent()
-        serializer.appendFormat("{0} *{1};", self.valueTypeName, valueName)
-        serializer.newline()
-        serializer.emitIndent()
-        serializer.appendFormat("{0} {1};", self.valueTypeName, initValuename)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendLine("/* perform lookup */")
-        serializer.emitIndent()
-        program.config.serializeLookup(
-            serializer, self.dataMapName, keyname, valueName)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendFormat("if ({0} != NULL) ", valueName)
-        serializer.newline()
-        serializer.increaseIndent()
-        serializer.emitIndent()
-        serializer.appendFormat("__sync_fetch_and_add({0}, {1});",
-                                valueName, self.increment)
-        serializer.newline()
-        serializer.decreaseIndent()
-        serializer.emitIndent()
-
-        serializer.append("else ")
-        serializer.blockStart()
-        serializer.emitIndent()
-        serializer.appendFormat("{0} = {1};", initValuename, self.increment)
-        serializer.newline()
-
-        serializer.emitIndent()
-        program.config.serializeUpdate(
-            serializer, self.dataMapName, keyname, initValuename)
-        serializer.newline()
-        serializer.blockEnd(True)
diff --git a/src/cc/frontends/p4/compiler/ebpfDeparser.py b/src/cc/frontends/p4/compiler/ebpfDeparser.py
deleted file mode 100644 (file)
index bf3de39..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from collections import defaultdict, OrderedDict
-from compilationException import CompilationException
-from p4_hlir.hlir import parse_call, p4_field, p4_parse_value_set, \
-    P4_DEFAULT, p4_parse_state, p4_table, \
-    p4_conditional_node, p4_parser_exception, \
-    p4_header_instance, P4_NEXT
-
-import ebpfProgram
-import ebpfInstance
-import ebpfType
-import ebpfStructType
-from topoSorting import Graph
-from programSerializer import ProgramSerializer
-
-def produce_parser_topo_sorting(hlir):
-    # This function is copied from the P4 behavioral model implementation
-    header_graph = Graph()
-
-    def walk_rec(hlir, parse_state, prev_hdr_node, tag_stacks_index):
-        assert(isinstance(parse_state, p4_parse_state))
-        for call in parse_state.call_sequence:
-            call_type = call[0]
-            if call_type == parse_call.extract:
-                hdr = call[1]
-
-                if hdr.virtual:
-                    base_name = hdr.base_name
-                    current_index = tag_stacks_index[base_name]
-                    if current_index > hdr.max_index:
-                        return
-                    tag_stacks_index[base_name] += 1
-                    name = base_name + "[%d]" % current_index
-                    hdr = hlir.p4_header_instances[name]
-
-                if hdr not in header_graph:
-                    header_graph.add_node(hdr)
-                hdr_node = header_graph.get_node(hdr)
-
-                if prev_hdr_node:
-                    prev_hdr_node.add_edge_to(hdr_node)
-                else:
-                    header_graph.root = hdr
-                prev_hdr_node = hdr_node
-
-        for branch_case, next_state in parse_state.branch_to.items():
-            if not next_state:
-                continue
-            if not isinstance(next_state, p4_parse_state):
-                continue
-            walk_rec(hlir, next_state, prev_hdr_node, tag_stacks_index.copy())
-
-    start_state = hlir.p4_parse_states["start"]
-    walk_rec(hlir, start_state, None, defaultdict(int))
-
-    header_topo_sorting = header_graph.produce_topo_sorting()
-
-    return header_topo_sorting
-
-class EbpfDeparser(object):
-    def __init__(self, hlir):
-        header_topo_sorting = produce_parser_topo_sorting(hlir)
-        self.headerOrder = [hdr.name for hdr in header_topo_sorting]
-
-    def serialize(self, serializer, program):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        serializer.emitIndent()
-        serializer.blockStart()
-        serializer.emitIndent()
-        serializer.appendLine("/* Deparser */")
-        serializer.emitIndent()
-        serializer.appendFormat("{0} = 0;", program.offsetVariableName)
-        serializer.newline()
-        for h in self.headerOrder:
-            header = program.getHeaderInstance(h)
-            self.serializeHeaderEmit(header, serializer, program)
-        serializer.blockEnd(True)
-
-    def serializeHeaderEmit(self, header, serializer, program):
-        assert isinstance(header, ebpfInstance.EbpfHeader)
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-        p4header = header.hlirInstance
-        assert isinstance(p4header, p4_header_instance)
-
-        serializer.emitIndent()
-        serializer.appendFormat("if ({0}.{1}.valid) ",
-                                program.headerStructName, header.name)
-        serializer.blockStart()
-
-        if ebpfProgram.EbpfProgram.isArrayElementInstance(p4header):
-            ebpfStack = program.getStackInstance(p4header.base_name)
-            assert isinstance(ebpfStack, ebpfInstance.EbpfHeaderStack)
-
-            if isinstance(p4header.index, int):
-                index = "[" + str(p4header.index) + "]"
-            elif p4header.index is P4_NEXT:
-                index = "[" + ebpfStack.indexVar + "]"
-            else:
-                raise CompilationException(
-                    True, "Unexpected index for array {0}",
-                    p4header.index)
-            basetype = ebpfStack.basetype
-        else:
-            ebpfHeader = program.getHeaderInstance(p4header.name)
-            basetype = ebpfHeader.type
-            index = ""
-
-        alignment = 0
-        for field in basetype.fields:
-            assert isinstance(field, ebpfStructType.EbpfField)
-
-            self.serializeFieldEmit(serializer, p4header.base_name,
-                                    index, field, alignment, program)
-            alignment += field.widthInBits()
-            alignment = alignment % 8
-        serializer.blockEnd(True)
-
-    def serializeFieldEmit(self, serializer, name, index,
-                           field, alignment, program):
-        assert isinstance(index, str)
-        assert isinstance(name, str)
-        assert isinstance(field, ebpfStructType.EbpfField)
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(alignment, int)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        if field.name == "valid":
-            return
-
-        fieldToEmit = (program.headerStructName + "." + name +
-                       index + "." + field.name)
-        width = field.widthInBits()
-        if width <= 32:
-            store = self.generatePacketStore(fieldToEmit, 0, alignment,
-                                             width, program)
-            serializer.emitIndent()
-            serializer.appendLine(store)
-        else:
-            # Destination is bigger than 4 bytes and
-            # represented as a byte array.
-            b = (width + 7) / 8
-            for i in range(0, b):
-                serializer.emitIndent()
-                store = self.generatePacketStore(fieldToEmit + "["+str(i)+"]",
-                                                 i,
-                                                 alignment,
-                                                 8, program)
-                serializer.appendLine(store)
-
-        serializer.emitIndent()
-        serializer.appendFormat("{0} += {1};",
-                                program.offsetVariableName, width)
-        serializer.newline()
-
-    def generatePacketStore(self, value, offset, alignment, width, program):
-        assert width > 0
-        assert alignment < 8
-        assert isinstance(width, int)
-        assert isinstance(alignment, int)
-
-        return "bpf_dins_pkt({0}, {1} / 8 + {2}, {3}, {4}, {5});".format(
-            program.packetName,
-            program.offsetVariableName,
-            offset,
-            alignment,
-            width,
-            value
-        )
diff --git a/src/cc/frontends/p4/compiler/ebpfInstance.py b/src/cc/frontends/p4/compiler/ebpfInstance.py
deleted file mode 100644 (file)
index 822688f..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import p4_header_instance
-from ebpfType import EbpfType
-from compilationException import CompilationException
-from programSerializer import ProgramSerializer
-import typeFactory
-
-
-class EbpfInstanceBase(object):
-    def __init__(self):
-        pass
-
-
-class SimpleInstance(EbpfInstanceBase):
-    # A header or a metadata instance (but not array elements)
-    def __init__(self, hlirInstance, factory, isMetadata):
-        super(SimpleInstance, self).__init__()
-        self.hlirInstance = hlirInstance
-        self.name = hlirInstance.base_name
-        self.type = factory.build(hlirInstance.header_type, isMetadata)
-
-    def declare(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        self.type.declare(serializer, self.name, False)
-
-
-class EbpfHeader(SimpleInstance):
-    """ Represents a header instance from a P4 program """
-    def __init__(self, hlirHeaderInstance, factory):
-        super(EbpfHeader, self).__init__(hlirHeaderInstance, factory, False)
-        if hlirHeaderInstance.metadata:
-            raise CompilationException(True, "Metadata passed to EpbfHeader")
-        if hlirHeaderInstance.index is not None:
-            self.name += "_" + str(hlirHeaderInstance.index)
-
-
-class EbpfMetadata(SimpleInstance):
-    """Represents a metadata instance from a P4 program"""
-    def __init__(self, hlirMetadataInstance, factory):
-        super(EbpfMetadata, self).__init__(hlirMetadataInstance, factory, True)
-        if not hlirMetadataInstance.metadata:
-            raise CompilationException(
-                True, "Header instance passed to EpbfMetadata {0}",
-                hlirMetadataInstance)
-        if hlirMetadataInstance.index is not None:
-            raise CompilationException(
-                True, "Unexpected metadata array {0}", self.hlirInstance)
-        if hasattr(hlirMetadataInstance, "initializer"):
-            self.initializer = hlirMetadataInstance.initializer
-        else:
-            self.initializer = None
-
-    def emitInitializer(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        if self.initializer is None:
-            self.type.emitInitializer(serializer)
-        else:
-            for key in self.initializer.keys():
-                serializer.appendFormat(
-                    ".{0} = {1},", key, self.initializer[key])
-
-
-class EbpfHeaderStack(EbpfInstanceBase):
-    """Represents a header stack instance; there is one instance of
-    this class for each STACK, and not for each
-    element of the stack, as in the HLIR"""
-    def __init__(self, hlirInstance, indexVar, factory):
-        super(EbpfHeaderStack, self).__init__()
-
-        # indexVar: name of the ebpf variable that
-        # holds the current index for this stack
-        assert isinstance(indexVar, str)
-        assert isinstance(factory, typeFactory.EbpfTypeFactory)
-        assert isinstance(hlirInstance, p4_header_instance)
-
-        self.indexVar = indexVar
-        self.name = hlirInstance.base_name
-        self.basetype = factory.build(hlirInstance.header_type, False)
-        assert isinstance(self.basetype, EbpfType)
-        self.arraySize = hlirInstance.max_index + 1
-        self.hlirInstance = hlirInstance
-
-    def declare(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        self.basetype.declareArray(serializer, self.name, self.arraySize)
diff --git a/src/cc/frontends/p4/compiler/ebpfParser.py b/src/cc/frontends/p4/compiler/ebpfParser.py
deleted file mode 100644 (file)
index 300bc69..0000000
+++ /dev/null
@@ -1,427 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import parse_call, p4_field, p4_parse_value_set, \
-    P4_DEFAULT, p4_parse_state, p4_table, \
-    p4_conditional_node, p4_parser_exception, \
-    p4_header_instance, P4_NEXT
-import ebpfProgram
-import ebpfStructType
-import ebpfInstance
-import programSerializer
-from compilationException import *
-
-
-class EbpfParser(object):
-    def __init__(self, hlirParser):  # hlirParser is a P4 parser
-        self.parser = hlirParser
-        self.name = hlirParser.name
-
-    def serialize(self, serializer, program):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        serializer.emitIndent()
-        serializer.appendFormat("{0}: ", self.name)
-        serializer.blockStart()
-        for op in self.parser.call_sequence:
-            self.serializeOperation(serializer, op, program)
-
-        self.serializeBranch(serializer, self.parser.branch_on,
-                             self.parser.branch_to, program)
-
-        serializer.blockEnd(True)
-
-    def serializeSelect(self, selectVarName, serializer, branch_on, program):
-        # selectVarName - name of temp variable to use for the select expression
-        assert isinstance(selectVarName, str)
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        totalWidth = 0
-        switchValue = ""
-        for e in branch_on:
-            if isinstance(e, p4_field):
-                instance = e.instance
-                assert isinstance(instance, p4_header_instance)
-                index = ""
-
-                if ebpfProgram.EbpfProgram.isArrayElementInstance(instance):
-                    ebpfStack = program.getStackInstance(instance.base_name)
-                    assert isinstance(ebpfStack, ebpfInstance.EbpfHeaderStack)
-
-                    if isinstance(instance.index, int):
-                        index = "[" + str(instance.index) + "]"
-                    elif instance.index is P4_NEXT:
-                        index = "[" + ebpfStack.indexVar + "]"
-                    else:
-                        raise CompilationException(True,
-                            "Unexpected index for array {0}", instance.index)
-                    basetype = ebpfStack.basetype
-                    name = ebpfStack.name
-                else:
-                    ebpfHeader = program.getInstance(instance.name)
-                    assert isinstance(ebpfHeader, ebpfInstance.EbpfHeader)
-                    basetype = ebpfHeader.type
-                    name = ebpfHeader.name
-
-                ebpfField = basetype.getField(e.name)
-                assert isinstance(ebpfField, ebpfStructType.EbpfField)
-
-                totalWidth += ebpfField.widthInBits()
-                fieldReference = (program.headerStructName + "." + name +
-                                  index + "." + ebpfField.name)
-
-                if switchValue == "":
-                    switchValue = fieldReference
-                else:
-                    switchValue = ("(" + switchValue + " << " +
-                                   str(ebpfField.widthInBits()) + ")")
-                    switchValue = switchValue + " | " + fieldReference
-            elif isinstance(e, tuple):
-                switchValue = self.currentReferenceAsString(e, program)
-            else:
-                raise CompilationException(
-                    True, "Unexpected element in match {0}", e)
-
-        if totalWidth > 32:
-            raise NotSupportedException("{0}: Matching on {1}-bit value",
-                                        branch_on, totalWidth)
-        serializer.emitIndent()
-        serializer.appendFormat("{0}32 {1} = {2};",
-                                program.config.uprefix,
-                                selectVarName, switchValue)
-        serializer.newline()
-
-    def generatePacketLoad(self, startBit, width, alignment, program):
-        # Generates an expression that does a load_*, shift and mask
-        # to load 'width' bits starting at startBit from the current
-        # packet offset.
-        # alignment is an integer <= 8 that holds the current alignment
-        # of of the packet offset.
-        assert width > 0
-        assert alignment < 8
-        assert isinstance(startBit, int)
-        assert isinstance(width, int)
-        assert isinstance(alignment, int)
-
-        firstBitIndex = startBit + alignment
-        lastBitIndex = startBit + width + alignment - 1
-        firstWordIndex = firstBitIndex / 8
-        lastWordIndex = lastBitIndex / 8
-
-        wordsToRead = lastWordIndex - firstWordIndex + 1
-        if wordsToRead == 1:
-            load = "load_byte"
-            loadSize = 8
-        elif wordsToRead == 2:
-            load = "load_half"
-            loadSize = 16
-        elif wordsToRead <= 4:
-            load = "load_word"
-            loadSize = 32
-        elif wordsToRead <= 8:
-            load = "load_dword"
-            loadSize = 64
-        else:
-            raise CompilationException(True, "Attempt to load more than 1 word")
-
-        readtype = program.config.uprefix + str(loadSize)
-        loadInstruction = "{0}({1}, ({2} + {3}) / 8)".format(
-            load, program.packetName, program.offsetVariableName, startBit)
-        shift = loadSize - alignment - width
-        load = "(({0}) >> ({1}))".format(loadInstruction, shift)
-        if width != loadSize:
-            mask = " & EBPF_MASK({0}, {1})".format(readtype, width)
-        else:
-            mask = ""
-        return load + mask
-
-    def currentReferenceAsString(self, tpl, program):
-        # a string describing an expression of the form current(position, width)
-        # The assumption is that at this point the packet cursor is ALWAYS
-        # byte aligned.  This should be true because headers are supposed
-        # to have sizes an integral number of bytes.
-        assert isinstance(tpl, tuple)
-        if len(tpl) != 2:
-            raise CompilationException(
-                True, "{0} Expected a tuple with 2 elements", tpl)
-
-        minIndex = tpl[0]
-        totalWidth = tpl[1]
-        result = self.generatePacketLoad(
-            minIndex, totalWidth, 0, program) # alignment is 0
-        return result
-
-    def serializeCases(self, selectVarName, serializer, branch_to, program):
-        assert isinstance(selectVarName, str)
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        branches = 0
-        seenDefault = False
-        for e in branch_to.keys():
-            serializer.emitIndent()
-            value = branch_to[e]
-
-            if isinstance(e, int):
-                serializer.appendFormat("if ({0} == {1})", selectVarName, e)
-            elif isinstance(e, tuple):
-                serializer.appendFormat(
-                    "if (({0} & {1}) == {2})", selectVarName, e[0], e[1])
-            elif isinstance(e, p4_parse_value_set):
-                raise NotSupportedException("{0}: Parser value sets", e)
-            elif e is P4_DEFAULT:
-                seenDefault = True
-                if branches > 0:
-                    serializer.append("else")
-            else:
-                raise CompilationException(
-                    True, "Unexpected element in match case {0}", e)
-
-            branches += 1
-            serializer.newline()
-            serializer.increaseIndent()
-            serializer.emitIndent()
-
-            label = program.getLabel(value)
-
-            if isinstance(value, p4_parse_state):
-                serializer.appendFormat("goto {0};", label)
-            elif isinstance(value, p4_table):
-                serializer.appendFormat("goto {0};", label)
-            elif isinstance(value, p4_conditional_node):
-                serializer.appendFormat("goto {0};", label)
-            elif isinstance(value, p4_parser_exception):
-                raise CompilationException(True, "Not yet implemented")
-            else:
-                raise CompilationException(
-                    True, "Unexpected element in match case {0}", value)
-
-            serializer.decreaseIndent()
-            serializer.newline()
-
-        # Must create default if it is missing
-        if not seenDefault:
-            serializer.emitIndent()
-            serializer.appendFormat(
-                "{0} = p4_pe_unhandled_select;", program.errorName)
-            serializer.newline()
-            serializer.emitIndent()
-            serializer.appendFormat("default: goto end;")
-            serializer.newline()
-
-    def serializeBranch(self, serializer, branch_on, branch_to, program):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        if branch_on == []:
-            dest = branch_to.values()[0]
-            serializer.emitIndent()
-            name = program.getLabel(dest)
-            serializer.appendFormat("goto {0};", name)
-            serializer.newline()
-        elif isinstance(branch_on, list):
-            tmpvar = program.generateNewName("tmp")
-            self.serializeSelect(tmpvar, serializer, branch_on, program)
-            self.serializeCases(tmpvar, serializer, branch_to, program)
-        else:
-            raise CompilationException(
-                True, "Unexpected branch_on {0}", branch_on)
-
-    def serializeOperation(self, serializer, op, program):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        operation = op[0]
-        if operation is parse_call.extract:
-            self.serializeExtract(serializer, op[1], program)
-        elif operation is parse_call.set:
-            self.serializeMetadataSet(serializer, op[1], op[2], program)
-        else:
-            raise CompilationException(
-                True, "Unexpected operation in parser {0}", op)
-
-    def serializeFieldExtract(self, serializer, headerInstanceName,
-                              index, field, alignment, program):
-        assert isinstance(index, str)
-        assert isinstance(headerInstanceName, str)
-        assert isinstance(field, ebpfStructType.EbpfField)
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        assert isinstance(alignment, int)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        fieldToExtractTo = headerInstanceName + index + "." + field.name
-
-        serializer.emitIndent()
-        width = field.widthInBits()
-        if field.name == "valid":
-            serializer.appendFormat(
-                "{0}.{1} = 1;", program.headerStructName, fieldToExtractTo)
-            serializer.newline()
-            return
-
-        serializer.appendFormat("if ({0}->len < BYTES({1} + {2})) ",
-                                program.packetName,
-                                program.offsetVariableName, width)
-        serializer.blockStart()
-        serializer.emitIndent()
-        serializer.appendFormat("{0} = p4_pe_header_too_short;",
-                                program.errorName)
-        serializer.newline()
-        serializer.emitIndent()
-        serializer.appendLine("goto end;")
-        # TODO: jump to correct exception handler
-        serializer.blockEnd(True)
-
-        if width <= 32:
-            serializer.emitIndent()
-            load = self.generatePacketLoad(0, width, alignment, program)
-
-            serializer.appendFormat("{0}.{1} = {2};",
-                                    program.headerStructName,
-                                    fieldToExtractTo, load)
-            serializer.newline()
-        else:
-            # Destination is bigger than 4 bytes and
-            # represented as a byte array.
-            if alignment == 0:
-                shift = 0
-            else:
-                shift = 8 - alignment
-
-            assert shift >= 0
-            if shift == 0:
-                method = "load_byte"
-            else:
-                method = "load_half"
-            b = (width + 7) / 8
-            for i in range(0, b):
-                serializer.emitIndent()
-                serializer.appendFormat("{0}.{1}[{2}] = ({3}8)",
-                                        program.headerStructName,
-                                        fieldToExtractTo, i,
-                                        program.config.uprefix)
-                serializer.appendFormat("(({0}({1}, ({2} / 8) + {3}) >> {4})",
-                                        method, program.packetName,
-                                        program.offsetVariableName, i, shift)
-                if (i == b - 1) and (width % 8 != 0):
-                    serializer.appendFormat(" & EBPF_MASK({0}8, {1})",
-                                            program.config.uprefix, width % 8)
-                serializer.append(")")
-                serializer.endOfStatement(True)
-
-        serializer.emitIndent()
-        serializer.appendFormat("{0} += {1};",
-                                program.offsetVariableName, width)
-        serializer.newline()
-
-    def serializeExtract(self, serializer, headerInstance, program):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        assert isinstance(headerInstance, p4_header_instance)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        if ebpfProgram.EbpfProgram.isArrayElementInstance(headerInstance):
-            ebpfStack = program.getStackInstance(headerInstance.base_name)
-            assert isinstance(ebpfStack, ebpfInstance.EbpfHeaderStack)
-
-            # write bounds check
-            serializer.emitIndent()
-            serializer.appendFormat("if ({0} >= {1}) ",
-                                    ebpfStack.indexVar, ebpfStack.arraySize)
-            serializer.blockStart()
-            serializer.emitIndent()
-            serializer.appendFormat("{0} = p4_pe_index_out_of_bounds;",
-                                    program.errorName)
-            serializer.newline()
-            serializer.emitIndent()
-            serializer.appendLine("goto end;")
-            serializer.blockEnd(True)
-
-            if isinstance(headerInstance.index, int):
-                index = "[" + str(headerInstance.index) + "]"
-            elif headerInstance.index is P4_NEXT:
-                index = "[" + ebpfStack.indexVar + "]"
-            else:
-                raise CompilationException(
-                    True, "Unexpected index for array {0}",
-                    headerInstance.index)
-            basetype = ebpfStack.basetype
-        else:
-            ebpfHeader = program.getHeaderInstance(headerInstance.name)
-            basetype = ebpfHeader.type
-            index = ""
-
-        # extract all fields
-        alignment = 0
-        for field in basetype.fields:
-            assert isinstance(field, ebpfStructType.EbpfField)
-
-            self.serializeFieldExtract(serializer, headerInstance.base_name,
-                                       index, field, alignment, program)
-            alignment += field.widthInBits()
-            alignment = alignment % 8
-
-        if ebpfProgram.EbpfProgram.isArrayElementInstance(headerInstance):
-            # increment stack index
-            ebpfStack = program.getStackInstance(headerInstance.base_name)
-            assert isinstance(ebpfStack, ebpfInstance.EbpfHeaderStack)
-
-            # write bounds check
-            serializer.emitIndent()
-            serializer.appendFormat("{0}++;", ebpfStack.indexVar)
-            serializer.newline()
-
-    def serializeMetadataSet(self, serializer, field, value, program):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-        assert isinstance(field, p4_field)
-
-        dest = program.getInstance(field.instance.name)
-        assert isinstance(dest, ebpfInstance.SimpleInstance)
-        destType = dest.type
-        assert isinstance(destType, ebpfStructType.EbpfStructType)
-        destField = destType.getField(field.name)
-
-        if destField.widthInBits() > 32:
-            useMemcpy = True
-            bytesToCopy = destField.widthInBits() / 8
-            if destField.widthInBits() % 8 != 0:
-                raise CompilationException(
-                    True,
-                    "{0}: Not implemented: wide field w. sz not multiple of 8",
-                    field)
-        else:
-            useMemcpy = False
-            bytesToCopy = None # not needed, but compiler is confused
-
-        serializer.emitIndent()
-        destination = "{0}.{1}.{2}".format(
-            program.metadataStructName, dest.name, destField.name)
-        if isinstance(value, int):
-            source = str(value)
-            if useMemcpy:
-                raise CompilationException(
-                    True,
-                    "{0}: Not implemented: copying from wide constant",
-                    value)
-        elif isinstance(value, tuple):
-            source = self.currentReferenceAsString(value, program)
-        elif isinstance(value, p4_field):
-            source = program.getInstance(value.instance.name)
-            if isinstance(source, ebpfInstance.EbpfMetadata):
-                sourceStruct = program.metadataStructName
-            else:
-                sourceStruct = program.headerStructName
-            source = "{0}.{1}.{2}".format(sourceStruct, source.name, value.name)
-        else:
-            raise CompilationException(
-                True, "Unexpected type for parse_call.set {0}", value)
-
-        if useMemcpy:
-            serializer.appendFormat("memcpy(&{0}, &{1}, {2})",
-                                    destination, source, bytesToCopy)
-        else:
-            serializer.appendFormat("{0} = {1}", destination, source)
-
-        serializer.endOfStatement(True)
diff --git a/src/cc/frontends/p4/compiler/ebpfProgram.py b/src/cc/frontends/p4/compiler/ebpfProgram.py
deleted file mode 100644 (file)
index 1237175..0000000
+++ /dev/null
@@ -1,506 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import p4_header_instance, p4_table, \
-     p4_conditional_node, p4_action, p4_parse_state
-from p4_hlir.main import HLIR
-import typeFactory
-import ebpfTable
-import ebpfParser
-import ebpfAction
-import ebpfInstance
-import ebpfConditional
-import ebpfCounter
-import ebpfDeparser
-import programSerializer
-import target
-from compilationException import *
-
-
-class EbpfProgram(object):
-    def __init__(self, name, hlir, isRouter, config):
-        """Representation of an EbpfProgram (in fact,
-        a C program that is converted to EBPF)"""
-        assert isinstance(hlir, HLIR)
-        assert isinstance(isRouter, bool)
-        assert isinstance(config, target.TargetConfig)
-
-        self.hlir = hlir
-        self.name = name
-        self.uniqueNameCounter = 0
-        self.config = config
-        self.isRouter = isRouter
-        self.reservedPrefix = "ebpf_"
-
-        assert isinstance(config, target.TargetConfig)
-
-        self.packetName = self.reservedPrefix + "packet"
-        self.dropBit = self.reservedPrefix + "drop"
-        self.license = "GPL"
-        self.offsetVariableName = self.reservedPrefix + "packetOffsetInBits"
-        self.zeroKeyName = self.reservedPrefix + "zero"
-        self.arrayIndexType = self.config.uprefix + "32"
-        # all array tables must be indexed with u32 values
-
-        self.errorName = self.reservedPrefix + "error"
-        self.functionName = self.reservedPrefix + "filter"
-        self.egressPortName = "egress_port" # Hardwired in P4 definition
-
-        self.typeFactory = typeFactory.EbpfTypeFactory(config)
-        self.errorCodes = [
-            "p4_pe_no_error",
-            "p4_pe_index_out_of_bounds",
-            "p4_pe_out_of_packet",
-            "p4_pe_header_too_long",
-            "p4_pe_header_too_short",
-            "p4_pe_unhandled_select",
-            "p4_pe_checksum"]
-
-        self.actions = []
-        self.conditionals = []
-        self.tables = []
-        self.headers = []   # header instances
-        self.metadata = []  # metadata instances
-        self.stacks = []    # header stack instances EbpfHeaderStack
-        self.parsers = []   # all parsers
-        self.deparser = None
-        self.entryPoints = []  # control-flow entry points from parser
-        self.counters = []
-        self.entryPointLabels = {}  # maps p4_node from entryPoints
-                                    # to labels in the C program
-        self.egressEntry = None
-
-        self.construct()
-
-        self.headersStructTypeName = self.reservedPrefix + "headers_t"
-        self.headerStructName = self.reservedPrefix + "headers"
-        self.metadataStructTypeName = self.reservedPrefix + "metadata_t"
-        self.metadataStructName = self.reservedPrefix + "metadata"
-
-    def construct(self):
-        if len(self.hlir.p4_field_list_calculations) > 0:
-            raise NotSupportedException(
-                "{0} calculated field",
-                self.hlir.p4_field_list_calculations.values()[0].name)
-
-        for h in self.hlir.p4_header_instances.values():
-            if h.max_index is not None:
-                assert isinstance(h, p4_header_instance)
-                if h.index == 0:
-                    # header stack; allocate only for zero-th index
-                    indexVarName = self.generateNewName(h.base_name + "_index")
-                    stack = ebpfInstance.EbpfHeaderStack(
-                        h, indexVarName, self.typeFactory)
-                    self.stacks.append(stack)
-            elif h.metadata:
-                metadata = ebpfInstance.EbpfMetadata(h, self.typeFactory)
-                self.metadata.append(metadata)
-            else:
-                header = ebpfInstance.EbpfHeader(h, self.typeFactory)
-                self.headers.append(header)
-
-        for p in self.hlir.p4_parse_states.values():
-            parser = ebpfParser.EbpfParser(p)
-            self.parsers.append(parser)
-
-        for a in self.hlir.p4_actions.values():
-            if self.isInternalAction(a):
-                continue
-            action = ebpfAction.EbpfAction(a, self)
-            self.actions.append(action)
-
-        for c in self.hlir.p4_counters.values():
-            counter = ebpfCounter.EbpfCounter(c, self)
-            self.counters.append(counter)
-
-        for t in self.hlir.p4_tables.values():
-            table = ebpfTable.EbpfTable(t, self, self.config)
-            self.tables.append(table)
-
-        for n in self.hlir.p4_ingress_ptr.keys():
-            self.entryPoints.append(n)
-
-        for n in self.hlir.p4_conditional_nodes.values():
-            conditional = ebpfConditional.EbpfConditional(n, self)
-            self.conditionals.append(conditional)
-
-        self.egressEntry = self.hlir.p4_egress_ptr
-        self.deparser = ebpfDeparser.EbpfDeparser(self.hlir)
-
-    def isInternalAction(self, action):
-        # This is a heuristic really to guess which actions are built-in
-        # Unfortunately there seems to be no other way to do this
-        return action.lineno < 0
-
-    @staticmethod
-    def isArrayElementInstance(headerInstance):
-        assert isinstance(headerInstance, p4_header_instance)
-        return headerInstance.max_index is not None
-
-    def emitWarning(self, formatString, *message):
-        assert isinstance(formatString, str)
-        print("WARNING: ", formatString.format(*message))
-
-    def toC(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-
-        self.generateIncludes(serializer)
-        self.generatePreamble(serializer)
-        self.generateTypes(serializer)
-        self.generateTables(serializer)
-
-        serializer.newline()
-        serializer.emitIndent()
-        self.config.serializeCodeSection(serializer)
-        serializer.newline()
-        serializer.emitIndent()
-        serializer.appendFormat("int {0}(struct __sk_buff* {1}) ",
-                                self.functionName, self.packetName)
-        serializer.blockStart()
-
-        self.generateHeaderInstance(serializer)
-        serializer.append(" = ")
-        self.generateInitializeHeaders(serializer)
-        serializer.endOfStatement(True)
-
-        self.generateMetadataInstance(serializer)
-        serializer.append(" = ")
-        self.generateInitializeMetadata(serializer)
-        serializer.endOfStatement(True)
-
-        self.createLocalVariables(serializer)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendLine("goto start;")
-
-        self.generateParser(serializer)
-        self.generatePipeline(serializer)
-
-        self.generateDeparser(serializer)
-
-        serializer.emitIndent()
-        serializer.appendLine("end:")
-        serializer.emitIndent()
-
-        if isinstance(self.config, target.KernelSamplesConfig):
-            serializer.appendFormat("return {0};", self.dropBit)
-            serializer.newline()
-        elif isinstance(self.config, target.BccConfig):
-            if self.isRouter:
-                serializer.appendFormat("if (!{0})", self.dropBit)
-                serializer.newline()
-                serializer.increaseIndent()
-                serializer.emitIndent()
-                serializer.appendFormat(
-                    "bpf_clone_redirect({0}, {1}.standard_metadata.{2}, 0);",
-                    self.packetName, self.metadataStructName,
-                    self.egressPortName)
-                serializer.newline()
-                serializer.decreaseIndent()
-
-                serializer.emitIndent()
-                serializer.appendLine(
-                    "return TC_ACT_SHOT /* drop packet; clone is forwarded */;")
-            else:
-                serializer.appendFormat(
-                    "return {1} ? TC_ACT_SHOT : TC_ACT_PIPE;",
-                    self.dropBit)
-                serializer.newline()
-        else:
-            raise CompilationException(
-                True, "Unexpected target configuration {0}",
-                self.config.targetName)
-        serializer.blockEnd(True)
-
-        self.generateLicense(serializer)
-
-        serializer.append(self.config.postamble)
-
-    def generateLicense(self, serializer):
-        self.config.serializeLicense(serializer, self.license)
-
-    # noinspection PyMethodMayBeStatic
-    def generateIncludes(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        serializer.append(self.config.getIncludes())
-
-    def getLabel(self, p4node):
-        # C label that corresponds to this point in the control-flow
-        if p4node is None:
-            return "end"
-        elif isinstance(p4node, p4_parse_state):
-            label = p4node.name
-            self.entryPointLabels[p4node.name] = label
-        if p4node.name not in self.entryPointLabels:
-            label = self.generateNewName(p4node.name)
-            self.entryPointLabels[p4node.name] = label
-        return self.entryPointLabels[p4node.name]
-
-    # noinspection PyMethodMayBeStatic
-    def generatePreamble(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-
-        serializer.emitIndent()
-        serializer.append("enum ErrorCode ")
-        serializer.blockStart()
-        for error in self.errorCodes:
-            serializer.emitIndent()
-            serializer.appendFormat("{0},", error)
-            serializer.newline()
-        serializer.blockEnd(False)
-        serializer.endOfStatement(True)
-        serializer.newline()
-
-        serializer.appendLine(
-            "#define EBPF_MASK(t, w) ((((t)(1)) << (w)) - (t)1)")
-        serializer.appendLine("#define BYTES(w) ((w + 7) / 8)")
-
-        self.config.generateDword(serializer)
-
-    # noinspection PyMethodMayBeStatic
-    def generateNewName(self, base):  # base is a string
-        """Generates a fresh name based on the specified base name"""
-        # TODO: this should be made "safer"
-        assert isinstance(base, str)
-
-        base += "_" + str(self.uniqueNameCounter)
-        self.uniqueNameCounter += 1
-        return base
-
-    def generateTypes(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-
-        for t in self.typeFactory.type_map.values():
-            t.serialize(serializer)
-
-        # generate a new struct type for the packet itself
-        serializer.appendFormat("struct {0} ", self.headersStructTypeName)
-        serializer.blockStart()
-        for h in self.headers:
-            serializer.emitIndent()
-            h.declare(serializer)
-            serializer.endOfStatement(True)
-
-        for h in self.stacks:
-            assert isinstance(h, ebpfInstance.EbpfHeaderStack)
-
-            serializer.emitIndent()
-            h.declare(serializer)
-            serializer.endOfStatement(True)
-
-        serializer.blockEnd(False)
-        serializer.endOfStatement(True)
-
-        # generate a new struct type for the metadata
-        serializer.appendFormat("struct {0} ", self.metadataStructTypeName)
-        serializer.blockStart()
-        for h in self.metadata:
-            assert isinstance(h, ebpfInstance.EbpfMetadata)
-
-            serializer.emitIndent()
-            h.declare(serializer)
-            serializer.endOfStatement(True)
-        serializer.blockEnd(False)
-        serializer.endOfStatement(True)
-
-    def generateTables(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-
-        for t in self.tables:
-            t.serialize(serializer, self)
-
-        for c in self.counters:
-            c.serialize(serializer, self)
-
-    def generateHeaderInstance(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-
-        serializer.emitIndent()
-        serializer.appendFormat(
-            "struct {0} {1}", self.headersStructTypeName, self.headerStructName)
-
-    def generateInitializeHeaders(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-
-        serializer.blockStart()
-        for h in self.headers:
-            serializer.emitIndent()
-            serializer.appendFormat(".{0} = ", h.name)
-            h.type.emitInitializer(serializer)
-            serializer.appendLine(",")
-        serializer.blockEnd(False)
-
-    def generateMetadataInstance(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-
-        serializer.emitIndent()
-        serializer.appendFormat(
-            "struct {0} {1}",
-            self.metadataStructTypeName,
-            self.metadataStructName)
-
-    def generateDeparser(self, serializer):
-        self.deparser.serialize(serializer, self)
-
-    def generateInitializeMetadata(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-
-        serializer.blockStart()
-        for h in self.metadata:
-            serializer.emitIndent()
-            serializer.appendFormat(".{0} = ", h.name)
-            h.emitInitializer(serializer)
-            serializer.appendLine(",")
-        serializer.blockEnd(False)
-
-    def createLocalVariables(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-
-        serializer.emitIndent()
-        serializer.appendFormat("unsigned {0} = 0;", self.offsetVariableName)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendFormat(
-            "enum ErrorCode {0} = p4_pe_no_error;", self.errorName)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendFormat(
-            "{0}8 {1} = 0;", self.config.uprefix, self.dropBit)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendFormat(
-            "{0} {1} = 0;", self.arrayIndexType, self.zeroKeyName)
-        serializer.newline()
-
-        for h in self.stacks:
-            serializer.emitIndent()
-            serializer.appendFormat(
-                "{0}8 {0} = 0;", self.config.uprefix, h.indexVar)
-            serializer.newline()
-
-    def getStackInstance(self, name):
-        assert isinstance(name, str)
-
-        for h in self.stacks:
-            if h.name == name:
-                assert isinstance(h, ebpfInstance.EbpfHeaderStack)
-                return h
-        raise CompilationException(
-            True, "Could not locate header stack named {0}", name)
-
-    def getHeaderInstance(self, name):
-        assert isinstance(name, str)
-
-        for h in self.headers:
-            if h.name == name:
-                assert isinstance(h, ebpfInstance.EbpfHeader)
-                return h
-        raise CompilationException(
-            True, "Could not locate header instance named {0}", name)
-
-    def getInstance(self, name):
-        assert isinstance(name, str)
-
-        for h in self.headers:
-            if h.name == name:
-                return h
-        for h in self.metadata:
-            if h.name == name:
-                return h
-        raise CompilationException(
-            True, "Could not locate instance named {0}", name)
-
-    def getAction(self, p4action):
-        assert isinstance(p4action, p4_action)
-        for a in self.actions:
-            if a.name == p4action.name:
-                return a
-
-        newAction = ebpfAction.BuiltinAction(p4action)
-        self.actions.append(newAction)
-        return newAction
-
-    def getTable(self, name):
-        assert isinstance(name, str)
-        for t in self.tables:
-            if t.name == name:
-                return t
-        raise CompilationException(
-            True, "Could not locate table named {0}", name)
-
-    def getCounter(self, name):
-        assert isinstance(name, str)
-        for t in self.counters:
-            if t.name == name:
-                return t
-        raise CompilationException(
-            True, "Could not locate counters named {0}", name)
-
-    def getConditional(self, name):
-        assert isinstance(name, str)
-        for c in self.conditionals:
-            if c.name == name:
-                return c
-        raise CompilationException(
-            True, "Could not locate conditional named {0}", name)
-
-    def generateParser(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        for p in self.parsers:
-            p.serialize(serializer, self)
-
-    def generateIngressPipeline(self, serializer):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        for t in self.tables:
-            assert isinstance(t, ebpfTable.EbpfTable)
-            serializer.emitIndent()
-            serializer.appendFormat("{0}:", t.name)
-            serializer.newline()
-
-    def generateControlFlowNode(self, serializer, node, nextEntryPoint):
-        # nextEntryPoint is used as a target whenever the target is None
-        # nextEntryPoint may also be None
-        if isinstance(node, p4_table):
-            table = self.getTable(node.name)
-            assert isinstance(table, ebpfTable.EbpfTable)
-            table.serializeCode(serializer, self, nextEntryPoint)
-        elif isinstance(node, p4_conditional_node):
-            conditional = self.getConditional(node.name)
-            assert isinstance(conditional, ebpfConditional.EbpfConditional)
-            conditional.generateCode(serializer, self, nextEntryPoint)
-        else:
-            raise CompilationException(
-                True, "{0} Unexpected control flow node ", node)
-
-    def generatePipelineInternal(self, serializer, nodestoadd, nextEntryPoint):
-        assert isinstance(serializer, programSerializer.ProgramSerializer)
-        assert isinstance(nodestoadd, set)
-
-        done = set()
-        while len(nodestoadd) > 0:
-            todo = nodestoadd.pop()
-            if todo in done:
-                continue
-            if todo is None:
-                continue
-
-            print("Generating ", todo.name)
-
-            done.add(todo)
-            self.generateControlFlowNode(serializer, todo, nextEntryPoint)
-
-            for n in todo.next_.values():
-                nodestoadd.add(n)
-
-    def generatePipeline(self, serializer):
-        todo = set()
-        for e in self.entryPoints:
-            todo.add(e)
-        self.generatePipelineInternal(serializer, todo, self.egressEntry)
-        todo = set()
-        todo.add(self.egressEntry)
-        self.generatePipelineInternal(serializer, todo, None)
diff --git a/src/cc/frontends/p4/compiler/ebpfScalarType.py b/src/cc/frontends/p4/compiler/ebpfScalarType.py
deleted file mode 100644 (file)
index cb5db21..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import P4_AUTO_WIDTH
-from ebpfType import *
-from compilationException import *
-from programSerializer import ProgramSerializer
-
-
-class EbpfScalarType(EbpfType):
-    __doc__ = "Represents a scalar type"
-    def __init__(self, parent, widthInBits, isSigned, config):
-        super(EbpfScalarType, self).__init__(None)
-        assert isinstance(widthInBits, int)
-        assert isinstance(isSigned, bool)
-        self.width = widthInBits
-        self.isSigned = isSigned
-        self.config = config
-        if widthInBits is P4_AUTO_WIDTH:
-            raise NotSupportedException("{0} Variable-width field", parent)
-
-    def widthInBits(self):
-        return self.width
-
-    @staticmethod
-    def bytesRequired(width):
-        return (width + 7) / 8
-
-    def asString(self):
-        if self.isSigned:
-            prefix = self.config.iprefix
-        else:
-            prefix = self.config.uprefix
-
-        if self.width <= 8:
-            name = prefix + "8"
-        elif self.width <= 16:
-            name = prefix + "16"
-        elif self.width <= 32:
-            name = prefix + "32"
-        else:
-            name = "char*"
-        return name
-
-    def alignment(self):
-        if self.width <= 8:
-            return 1
-        elif self.width <= 16:
-            return 2
-        elif self.width <= 32:
-            return 4
-        else:
-            return 1  # Char array
-
-    def serialize(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        serializer.append(self.asString())
-
-    def declareArray(self, serializer, identifier, size):
-        raise CompilationException(
-            True, "Arrays of base type not expected in P4")
-
-    def declare(self, serializer, identifier, asPointer):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(asPointer, bool)
-        assert isinstance(identifier, str)
-
-        if self.width <= 32:
-            self.serialize(serializer)
-            if asPointer:
-                serializer.append("*")
-            serializer.space()
-            serializer.append(identifier)
-        else:
-            if asPointer:
-                serializer.append("char*")
-            else:
-                serializer.appendFormat(
-                    "char {0}[{1}]", identifier,
-                    EbpfScalarType.bytesRequired(self.width))
-
-    def emitInitializer(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        serializer.append("0")
diff --git a/src/cc/frontends/p4/compiler/ebpfStructType.py b/src/cc/frontends/p4/compiler/ebpfStructType.py
deleted file mode 100644 (file)
index e279bc6..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import P4_SIGNED, P4_SATURATING
-from ebpfScalarType import *
-
-
-class EbpfField(object):
-    __doc__ = "represents a field in a struct type, not in an instance"
-
-    def __init__(self, hlirParentType, name, widthInBits, attributes, config):
-        self.name = name
-        self.width = widthInBits
-        self.hlirType = hlirParentType
-        signed = False
-        if P4_SIGNED in attributes:
-            signed = True
-        if P4_SATURATING in attributes:
-            raise NotSupportedException(
-                "{0}.{1}: Saturated types", self.hlirType, self.name)
-
-        try:
-            self.type = EbpfScalarType(
-                self.hlirType, widthInBits, signed, config)
-        except CompilationException as e:
-            raise CompilationException(
-                e.isBug, "{0}.{1}: {2}", hlirParentType, self.name, e.show())
-
-    def widthInBits(self):
-        return self.width
-
-
-class EbpfStructType(EbpfType):
-    # Abstract base class for HeaderType and MetadataType.
-    # They are both represented by a p4 header_type
-    def __init__(self, hlirHeader, config):
-        super(EbpfStructType, self).__init__(hlirHeader)
-        self.name = hlirHeader.name
-        self.fields = []
-
-        for (fieldName, fieldSize) in self.hlirType.layout.items():
-            attributes = self.hlirType.attributes[fieldName]
-            field = EbpfField(
-                hlirHeader, fieldName, fieldSize, attributes, config)
-            self.fields.append(field)
-
-    def serialize(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-
-        serializer.emitIndent()
-        serializer.appendFormat("struct {0} ", self.name)
-        serializer.blockStart()
-
-        for field in self.fields:
-            serializer.emitIndent()
-            field.type.declare(serializer, field.name, False)
-            serializer.appendFormat("; /* {0} bits */", field.widthInBits())
-            serializer.newline()
-
-        serializer.blockEnd(False)
-        serializer.endOfStatement(True)
-
-    def declare(self, serializer, identifier, asPointer):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(identifier, str)
-        assert isinstance(asPointer, bool)
-
-        serializer.appendFormat("struct {0} ", self.name)
-        if asPointer:
-            serializer.append("*")
-        serializer.append(identifier)
-
-    def widthInBits(self):
-        return self.hlirType.length * 8
-
-    def getField(self, name):
-        assert isinstance(name, str)
-
-        for f in self.fields:
-            assert isinstance(f, EbpfField)
-            if f.name == name:
-                return f
-        raise CompilationException(
-            True, "Could not locate field {0}.{1}", self, name)
-
-
-class EbpfHeaderType(EbpfStructType):
-    def __init__(self, hlirHeader, config):
-        super(EbpfHeaderType, self).__init__(hlirHeader, config)
-        validField = EbpfField(hlirHeader, "valid", 1, set(), config)
-        # check that no "valid" field exists already
-        for f in self.fields:
-            if f.name == "valid":
-                raise CompilationException(
-                    True,
-                    "Header type contains a field named `valid': {0}",
-                    f)
-        self.fields.append(validField)
-
-    def emitInitializer(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        serializer.blockStart()
-        serializer.emitIndent()
-        serializer.appendLine(".valid = 0")
-        serializer.blockEnd(False)
-
-    def declareArray(self, serializer, identifier, size):
-        assert isinstance(serializer, ProgramSerializer)
-        serializer.appendFormat(
-            "struct {0} {1}[{2}]", self.name, identifier, size)
-
-
-class EbpfMetadataType(EbpfStructType):
-    def __init__(self, hlirHeader, config):
-        super(EbpfMetadataType, self).__init__(hlirHeader, config)
-
-    def emitInitializer(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-
-        serializer.blockStart()
-        for field in self.fields:
-            serializer.emitIndent()
-            serializer.appendFormat(".{0} = ", field.name)
-
-            field.type.emitInitializer(serializer)
-            serializer.append(",")
-            serializer.newline()
-        serializer.blockEnd(False)
diff --git a/src/cc/frontends/p4/compiler/ebpfTable.py b/src/cc/frontends/p4/compiler/ebpfTable.py
deleted file mode 100644 (file)
index 5325028..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import p4_match_type, p4_field, p4_table, p4_header_instance
-from programSerializer import ProgramSerializer
-from compilationException import *
-import ebpfProgram
-import ebpfInstance
-import ebpfCounter
-import ebpfStructType
-import ebpfAction
-
-
-class EbpfTableKeyField(object):
-    def __init__(self, fieldname, instance, field, mask):
-        assert isinstance(instance, ebpfInstance.EbpfInstanceBase)
-        assert isinstance(field, ebpfStructType.EbpfField)
-
-        self.keyFieldName = fieldname
-        self.instance = instance
-        self.field = field
-        self.mask = mask
-
-    def serializeType(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        ftype = self.field.type
-        serializer.emitIndent()
-        ftype.declare(serializer, self.keyFieldName, False)
-        serializer.endOfStatement(True)
-
-    def serializeConstruction(self, keyName, serializer, program):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(keyName, str)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        if self.mask is not None:
-            maskExpression = " & {0}".format(self.mask)
-        else:
-            maskExpression = ""
-
-        if isinstance(self.instance, ebpfInstance.EbpfMetadata):
-            base = program.metadataStructName
-        else:
-            base = program.headerStructName
-
-        if isinstance(self.instance, ebpfInstance.SimpleInstance):
-            source = "{0}.{1}.{2}".format(
-                base, self.instance.name, self.field.name)
-        else:
-            assert isinstance(self.instance, ebpfInstance.EbpfHeaderStack)
-            source = "{0}.{1}[{2}].{3}".format(
-                base, self.instance.name,
-                self.instance.hlirInstance.index, self.field.name)
-        destination = "{0}.{1}".format(keyName, self.keyFieldName)
-        size = self.field.widthInBits()
-
-        serializer.emitIndent()
-        if size <= 32:
-            serializer.appendFormat("{0} = ({1}){2};",
-                                    destination, source, maskExpression)
-        else:
-            if maskExpression != "":
-                raise NotSupportedException(
-                    "{0} Mask wider than 32 bits", self.field.hlirType)
-            serializer.appendFormat(
-                "memcpy(&{0}, &{1}, {2});", destination, source, size / 8)
-
-        serializer.newline()
-
-
-class EbpfTableKey(object):
-    def __init__(self, match_fields, program):
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        self.expressions = []
-        self.fields = []
-        self.masks = []
-        self.fieldNamePrefix = "key_field_"
-        self.program = program
-
-        fieldNumber = 0
-        for f in match_fields:
-            field = f[0]
-            matchType = f[1]
-            mask = f[2]
-
-            if ((matchType is p4_match_type.P4_MATCH_TERNARY) or
-                (matchType is p4_match_type.P4_MATCH_LPM) or
-                (matchType is p4_match_type.P4_MATCH_RANGE)):
-                raise NotSupportedException(
-                    False, "Match type {0}", matchType)
-
-            if matchType is p4_match_type.P4_MATCH_VALID:
-                # we should be really checking the valid field;
-                # p4_field is a header instance
-                assert isinstance(field, p4_header_instance)
-                instance = field
-                fieldname = "valid"
-            else:
-                assert isinstance(field, p4_field)
-                instance = field.instance
-                fieldname = field.name
-
-            if ebpfProgram.EbpfProgram.isArrayElementInstance(instance):
-                ebpfStack = program.getStackInstance(instance.base_name)
-                assert isinstance(ebpfStack, ebpfInstance.EbpfHeaderStack)
-                basetype = ebpfStack.basetype
-                eInstance = program.getStackInstance(instance.base_name)
-            else:
-                ebpfHeader = program.getInstance(instance.name)
-                assert isinstance(ebpfHeader, ebpfInstance.SimpleInstance)
-                basetype = ebpfHeader.type
-                eInstance = program.getInstance(instance.name)
-
-            ebpfField = basetype.getField(fieldname)
-            assert isinstance(ebpfField, ebpfStructType.EbpfField)
-
-            fieldName = self.fieldNamePrefix + str(fieldNumber)
-            fieldNumber += 1
-            keyField = EbpfTableKeyField(fieldName, eInstance, ebpfField, mask)
-
-            self.fields.append(keyField)
-            self.masks.append(mask)
-
-    @staticmethod
-    def fieldRank(field):
-        assert isinstance(field, EbpfTableKeyField)
-        return field.field.type.alignment()
-
-    def serializeType(self, serializer, keyTypeName):
-        assert isinstance(serializer, ProgramSerializer)
-        serializer.emitIndent()
-        serializer.appendFormat("struct {0} ", keyTypeName)
-        serializer.blockStart()
-
-        # Sort fields in decreasing size; this will ensure that
-        # there is no padding.
-        # Padding may cause the ebpf verification to fail,
-        # since padding fields are not initialized
-        fieldOrder = sorted(
-            self.fields, key=EbpfTableKey.fieldRank, reverse=True)
-        for f in fieldOrder:
-            assert isinstance(f, EbpfTableKeyField)
-            f.serializeType(serializer)
-
-        serializer.blockEnd(False)
-        serializer.endOfStatement(True)
-
-    def serializeConstruction(self, serializer, keyName, program):
-        serializer.emitIndent()
-        serializer.appendLine("/* construct key */")
-
-        for f in self.fields:
-            f.serializeConstruction(keyName, serializer, program)
-
-
-class EbpfTable(object):
-    # noinspection PyUnresolvedReferences
-    def __init__(self, hlirtable, program, config):
-        assert isinstance(hlirtable, p4_table)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        self.name = hlirtable.name
-        self.hlirtable = hlirtable
-        self.config = config
-
-        self.defaultActionMapName = (program.reservedPrefix +
-                                     self.name + "_miss")
-        self.key = EbpfTableKey(hlirtable.match_fields, program)
-        self.size = hlirtable.max_size
-        if self.size is None:
-            program.emitWarning(
-                "{0} does not specify a max_size; using 1024", hlirtable)
-            self.size = 1024
-        self.isHash = True  # TODO: try to guess arrays when possible
-        self.dataMapName = self.name
-        self.actionEnumName = program.generateNewName(self.name + "_actions")
-        self.keyTypeName = program.generateNewName(self.name + "_key")
-        self.valueTypeName = program.generateNewName(self.name + "_value")
-        self.actions = []
-
-        if hlirtable.action_profile is not None:
-            raise NotSupportedException("{0}: action_profile tables",
-                                        hlirtable)
-        if hlirtable.support_timeout:
-            program.emitWarning("{0}: table timeout {1}; ignoring",
-                                hlirtable, NotSupportedException.archError)
-
-        self.counters = []
-        if (hlirtable.attached_counters is not None):
-            for c in hlirtable.attached_counters:
-                ctr = program.getCounter(c.name)
-                assert isinstance(ctr, ebpfCounter.EbpfCounter)
-                self.counters.append(ctr)
-
-        if (len(hlirtable.attached_meters) > 0 or
-            len(hlirtable.attached_registers) > 0):
-            program.emitWarning("{0}: meters/registers {1}; ignored",
-                                hlirtable, NotSupportedException.archError)
-
-        for a in hlirtable.actions:
-            action = program.getAction(a)
-            self.actions.append(action)
-
-    def serializeKeyType(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        self.key.serializeType(serializer, self.keyTypeName)
-
-    def serializeActionArguments(self, serializer, action):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(action, ebpfAction.EbpfActionBase)
-        action.serializeArgumentsAsStruct(serializer)
-
-    def serializeValueType(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        #  create an enum with tags for all actions
-        serializer.emitIndent()
-        serializer.appendFormat("enum {0} ", self.actionEnumName)
-        serializer.blockStart()
-
-        for a in self.actions:
-            name = a.name
-            serializer.emitIndent()
-            serializer.appendFormat("{0}_{1},", self.name, name)
-            serializer.newline()
-
-        serializer.blockEnd(False)
-        serializer.endOfStatement(True)
-
-        # a type-safe union: a struct with a tag and an union
-        serializer.emitIndent()
-        serializer.appendFormat("struct {0} ", self.valueTypeName)
-        serializer.blockStart()
-
-        serializer.emitIndent()
-        #serializer.appendFormat("enum {0} action;", self.actionEnumName)
-        # teporary workaround bcc bug
-        serializer.appendFormat("{0}32 action;",
-                                self.config.uprefix)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.append("union ")
-        serializer.blockStart()
-
-        for a in self.actions:
-            self.serializeActionArguments(serializer, a)
-
-        serializer.blockEnd(False)
-        serializer.space()
-        serializer.appendLine("u;")
-        serializer.blockEnd(False)
-        serializer.endOfStatement(True)
-
-    def serialize(self, serializer, program):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        self.serializeKeyType(serializer)
-        self.serializeValueType(serializer)
-
-        self.config.serializeTableDeclaration(
-            serializer, self.dataMapName, self.isHash,
-            "struct " + self.keyTypeName,
-            "struct " + self.valueTypeName, self.size)
-        self.config.serializeTableDeclaration(
-            serializer, self.defaultActionMapName, False,
-            program.arrayIndexType, "struct " + self.valueTypeName, 1)
-
-    def serializeCode(self, serializer, program, nextNode):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(program, ebpfProgram.EbpfProgram)
-
-        hitVarName = program.reservedPrefix + "hit"
-        keyname = "key"
-        valueName = "value"
-
-        serializer.newline()
-        serializer.emitIndent()
-        serializer.appendFormat("{0}:", program.getLabel(self))
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.blockStart()
-
-        serializer.emitIndent()
-        serializer.appendFormat("{0}8 {1};", program.config.uprefix, hitVarName)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendFormat("struct {0} {1} = {{}};", self.keyTypeName, keyname)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendFormat(
-            "struct {0} *{1};", self.valueTypeName, valueName)
-        serializer.newline()
-
-        self.key.serializeConstruction(serializer, keyname, program)
-
-        serializer.emitIndent()
-        serializer.appendFormat("{0} = 1;", hitVarName)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendLine("/* perform lookup */")
-        serializer.emitIndent()
-        program.config.serializeLookup(
-            serializer, self.dataMapName, keyname, valueName)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendFormat("if ({0} == NULL) ", valueName)
-        serializer.blockStart()
-
-        serializer.emitIndent()
-        serializer.appendFormat("{0} = 0;", hitVarName)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendLine("/* miss; find default action */")
-        serializer.emitIndent()
-        program.config.serializeLookup(
-            serializer, self.defaultActionMapName,
-            program.zeroKeyName, valueName)
-        serializer.newline()
-        serializer.blockEnd(True)
-
-        if len(self.counters) > 0:
-            serializer.emitIndent()
-            serializer.append("else ")
-            serializer.blockStart()
-            for c in self.counters:
-                assert isinstance(c, ebpfCounter.EbpfCounter)
-                if c.autoIncrement:
-                    serializer.emitIndent()
-                    serializer.blockStart()
-                    c.serializeCode(keyname, serializer, program)
-                    serializer.blockEnd(True)
-            serializer.blockEnd(True)
-
-        serializer.emitIndent()
-        serializer.appendFormat("if ({0} != NULL) ", valueName)
-        serializer.blockStart()
-        serializer.emitIndent()
-        serializer.appendLine("/* run action */")
-        self.runAction(serializer, self.name, valueName, program, nextNode)
-
-        nextNode = self.hlirtable.next_
-        if "hit" in nextNode:
-            node = nextNode["hit"]
-            if node is None:
-                node = nextNode
-            label = program.getLabel(node)
-            serializer.emitIndent()
-            serializer.appendFormat("if (hit) goto {0};", label)
-            serializer.newline()
-
-            node = nextNode["miss"]
-            if node is None:
-                node = nextNode
-            label = program.getLabel(node)
-            serializer.emitIndent()
-            serializer.appendFormat("else goto {0};", label)
-            serializer.newline()
-
-        serializer.blockEnd(True)
-        if not "hit" in nextNode:
-            # Catch-all
-            serializer.emitIndent()
-            serializer.appendFormat("goto end;")
-            serializer.newline()
-
-        serializer.blockEnd(True)
-
-    def runAction(self, serializer, tableName, valueName, program, nextNode):
-        serializer.emitIndent()
-        serializer.appendFormat("switch ({0}->action) ", valueName)
-        serializer.blockStart()
-
-        for a in self.actions:
-            assert isinstance(a, ebpfAction.EbpfActionBase)
-
-            serializer.emitIndent()
-            serializer.appendFormat("case {0}_{1}: ", tableName, a.name)
-            serializer.newline()
-            serializer.emitIndent()
-            serializer.blockStart()
-            a.serializeBody(serializer, valueName, program)
-            serializer.blockEnd(True)
-            serializer.emitIndent()
-
-            nextNodes = self.hlirtable.next_
-            if a.hliraction in nextNodes:
-                node = nextNodes[a.hliraction]
-                if node is None:
-                    node = nextNode
-                label = program.getLabel(node)
-                serializer.appendFormat("goto {0};", label)
-            else:
-                serializer.appendFormat("break;")
-            serializer.newline()
-
-        serializer.blockEnd(True)
diff --git a/src/cc/frontends/p4/compiler/ebpfType.py b/src/cc/frontends/p4/compiler/ebpfType.py
deleted file mode 100644 (file)
index a652097..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from compilationException import CompilationException
-
-class EbpfType(object):
-    __doc__ = "Base class for representing a P4 type"
-
-    def __init__(self, hlirType):
-        self.hlirType = hlirType
-
-    # Methods to override
-
-    def serialize(self, serializer):
-        # the type itself
-        raise CompilationException(True, "Method must be overridden")
-
-    def declare(self, serializer, identifier, asPointer):
-        # declaration of an identifier with this type
-        # asPointer is a boolean;
-        # if true, the identifier is declared as a pointer
-        raise CompilationException(True, "Method must be overridden")
-
-    def emitInitializer(self, serializer):
-        # A default initializer suitable for this type
-        raise CompilationException(True, "Method must be overridden")
-
-    def declareArray(self, serializer, identifier, size):
-        # Declare an identifier with an array type with the specified size
-        raise CompilationException(True, "Method must be overridden")
diff --git a/src/cc/frontends/p4/compiler/p4toEbpf.py b/src/cc/frontends/p4/compiler/p4toEbpf.py
deleted file mode 100755 (executable)
index 8500ca5..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-# Compiler from P4 to EBPF
-# (See http://www.slideshare.net/PLUMgrid/ebpf-and-linux-networking).
-# This compiler in fact generates a C source file
-# which can be compiled to EBPF using the LLVM compiler
-# with the ebpf target.
-#
-# Main entry point.
-
-import argparse
-import os
-import traceback
-import sys
-import target
-from p4_hlir.main import HLIR
-from ebpfProgram import EbpfProgram
-from compilationException import *
-from programSerializer import ProgramSerializer
-
-
-def get_parser():
-    parser = argparse.ArgumentParser(description='p4toEbpf arguments')
-    parser.add_argument('source', metavar='source', type=str,
-                        help='a P4 source file to compile')
-    parser.add_argument('-g', dest='generated', default="router",
-                        help="kind of output produced: filter or router")
-    parser.add_argument('-o', dest='output_file', default="output.c",
-                        help="generated C file name")
-    return parser
-
-
-def process(input_args):
-    parser = get_parser()
-    args, unparsed_args = parser.parse_known_args(input_args)
-
-    has_remaining_args = False
-    preprocessor_args = []
-    for a in unparsed_args:
-        if a[:2] == "-D" or a[:2] == "-I" or a[:2] == "-U":
-            input_args.remove(a)
-            preprocessor_args.append(a)
-        else:
-            has_remaining_args = True
-
-    # trigger error
-    if has_remaining_args:
-        parser.parse_args(input_args)
-
-    if args.generated == "router":
-        isRouter = True
-    elif args.generated == "filter":
-        isRouter = False
-    else:
-        print("-g should be one of 'filter' or 'router'")
-
-    print("*** Compiling ", args.source)
-    return compileP4(args.source, args.output_file, isRouter, preprocessor_args)
-
-
-class CompileResult(object):
-    def __init__(self, kind, error):
-        self.kind = kind
-        self.error = error
-
-    def __str__(self):
-        if self.kind == "OK":
-            return "Compilation successful"
-        else:
-            return "Compilation failed with error: " + self.error
-
-
-def compileP4(inputFile, gen_file, isRouter, preprocessor_args):
-    h = HLIR(inputFile)
-
-    for parg in preprocessor_args:
-        h.add_preprocessor_args(parg)
-    if not h.build():
-        return CompileResult("HLIR", "Error while building HLIR")
-
-    try:
-        basename = os.path.basename(inputFile)
-        basename = os.path.splitext(basename)[0]
-
-        config = target.BccConfig()
-        e = EbpfProgram(basename, h, isRouter, config)
-        serializer = ProgramSerializer()
-        e.toC(serializer)
-        f = open(gen_file, 'w')
-        f.write(serializer.toString())
-        return CompileResult("OK", "")
-    except CompilationException as e:
-        prefix = ""
-        if e.isBug:
-            prefix = "### Compiler bug: "
-        return CompileResult("bug", prefix + e.show())
-    except NotSupportedException as e:
-        return CompileResult("not supported", e.show())
-    except:
-        return CompileResult("exception", traceback.format_exc())
-
-
-# main entry point
-if __name__ == "__main__":
-    result = process(sys.argv[1:])
-    if result.kind != "OK":
-        print(str(result))
diff --git a/src/cc/frontends/p4/compiler/programSerializer.py b/src/cc/frontends/p4/compiler/programSerializer.py
deleted file mode 100644 (file)
index 651e019..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-
-# helper for building C program source text
-
-from compilationException import *
-
-
-class ProgramSerializer(object):
-    def __init__(self):
-        self.program = ""
-        self.eol = "\n"
-        self.currentIndent = 0
-        self.INDENT_AMOUNT = 4  # default indent amount
-
-    def __str__(self):
-        return self.program
-
-    def increaseIndent(self):
-        self.currentIndent += self.INDENT_AMOUNT
-
-    def decreaseIndent(self):
-        self.currentIndent -= self.INDENT_AMOUNT
-        if self.currentIndent < 0:
-            raise CompilationException(True, "Negative indentation level")
-
-    def toString(self):
-        return self.program
-
-    def space(self):
-        self.append(" ")
-
-    def newline(self):
-        self.program += self.eol
-
-    def endOfStatement(self, addNewline):
-        self.append(";")
-        if addNewline:
-            self.newline()
-
-    def append(self, string):
-        self.program += str(string)
-
-    def appendFormat(self, format, *args):
-        string = format.format(*args)
-        self.append(string)
-
-    def appendLine(self, string):
-        self.append(string)
-        self.newline()
-
-    def emitIndent(self):
-        self.program += " " * self.currentIndent
-
-    def blockStart(self):
-        self.append("{")
-        self.newline()
-        self.increaseIndent()
-
-    def blockEnd(self, addNewline):
-        self.decreaseIndent()
-        self.emitIndent()
-        self.append("}")
-        if addNewline:
-            self.newline()
diff --git a/src/cc/frontends/p4/compiler/target.py b/src/cc/frontends/p4/compiler/target.py
deleted file mode 100644 (file)
index 9b5fb4d..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from programSerializer import ProgramSerializer
-
-# abstraction for isolating target-specific features
-
-# Base class for representing target-specific configuration
-class TargetConfig(object):
-    def __init__(self, target):
-        self.targetName = target
-
-    def getIncludes(self):
-        return ""
-
-    def serializeLookup(self, serializer, tableName, key, value):
-        serializer.appendFormat("{0} = bpf_map_lookup_elem(&{1}, &{2});",
-                                value, tableName, key)
-
-    def serializeUpdate(self, serializer, tableName, key, value):
-        serializer.appendFormat(
-            "bpf_map_update_elem(&{0}, &{1}, &{2}, BPF_ANY);",
-            tableName, key, value)
-
-    def serializeLicense(self, serializer, licenseString):
-        assert isinstance(serializer, ProgramSerializer)
-        serializer.emitIndent()
-        serializer.appendFormat(
-            "char _license[] {0}(\"license\") = \"{1}\";",
-            self.config.section, licenseString)
-        serializer.newline()
-
-    def serializeCodeSection(self, serializer):
-        assert isinstance(serializer, ProgramSerializer)
-        serializer.appendFormat("{0}(\"{1}\")", self.section, self.entrySection)
-
-    def serializeTableDeclaration(self, serializer, tableName,
-                                  isHash, keyType, valueType, size):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(tableName, str)
-        assert isinstance(isHash, bool)
-        assert isinstance(keyType, str)
-        assert isinstance(valueType, str)
-        assert isinstance(size, int)
-
-        serializer.emitIndent()
-        serializer.appendFormat("struct {0} {1}(\"maps\") {2} = ",
-                                self.tableName, self.section, tableName)
-        serializer.blockStart()
-
-        serializer.emitIndent()
-        serializer.append(".type = ")
-        if isHash:
-            serializer.appendLine("BPF_MAP_TYPE_HASH,")
-        else:
-            serializer.appendLine("BPF_MAP_TYPE_ARRAY,")
-
-        serializer.emitIndent()
-        serializer.appendFormat(".{0} = sizeof(struct {1}), ",
-                                self.tableKeyAttribute, keyType)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendFormat(".{0} = sizeof(struct {1}), ",
-                                self.tableValueAttribute, valueType)
-        serializer.newline()
-
-        serializer.emitIndent()
-        serializer.appendFormat(".{0} = {1}, ", self.tableSizeAttribute, size)
-        serializer.newline()
-
-        serializer.blockEnd(False)
-        serializer.endOfStatement(True)
-
-    def generateDword(self, serializer):
-        serializer.appendFormat(
-            "static inline {0}64 load_dword(void *skb, {0}64 off)",
-            self.uprefix)
-        serializer.newline()
-        serializer.blockStart()
-        serializer.emitIndent()
-        serializer.appendFormat(
-            ("return (({0}64)load_word(skb, off) << 32) | " +
-             "load_word(skb, off + 4);"),
-            self.uprefix)
-        serializer.newline()
-        serializer.blockEnd(True)
-
-
-# Represents a target that is compiled within the kernel
-# source tree samples folder and which attaches to a socket
-class KernelSamplesConfig(TargetConfig):
-    def __init__(self):
-        super(TargetConfig, self).__init__("Socket")
-        self.entrySection = "socket1"
-        self.section = "SEC"
-        self.uprefix = "u"
-        self.iprefix = "i"
-        self.tableKeyAttribute = "key_size"
-        self.tableValueAttribute = "value_size"
-        self.tableSizeAttribute = "max_entries"
-        self.tableName = "bpf_map_def"
-        self.postamble = ""
-
-    def getIncludes(self):
-        return """
-#include <uapi/linux/bpf.h>
-#include <uapi/linux/if_ether.h>
-#include <uapi/linux/if_packet.h>
-#include <uapi/linux/ip.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include "bpf_helpers.h"
-"""
-
-
-# Represents a target compiled by bcc that uses the TC
-class BccConfig(TargetConfig):
-    def __init__(self):
-        super(BccConfig, self).__init__("BCC")
-        self.uprefix = "u"
-        self.iprefix = "i"
-        self.postamble = ""
-
-    def serializeTableDeclaration(self, serializer, tableName,
-                                  isHash, keyType, valueType, size):
-        assert isinstance(serializer, ProgramSerializer)
-        assert isinstance(tableName, str)
-        assert isinstance(isHash, bool)
-        assert isinstance(keyType, str)
-        assert isinstance(valueType, str)
-        assert isinstance(size, int)
-
-        serializer.emitIndent()
-        if isHash:
-            kind = "hash"
-        else:
-            kind = "array"
-        serializer.appendFormat(
-            "BPF_TABLE(\"{0}\", {1}, {2}, {3}, {4});",
-            kind, keyType, valueType, tableName, size)
-        serializer.newline()
-
-    def serializeLookup(self, serializer, tableName, key, value):
-        serializer.appendFormat("{0} = {1}.lookup(&{2});",
-                                value, tableName, key)
-
-    def serializeUpdate(self, serializer, tableName, key, value):
-        serializer.appendFormat("{0}.update(&{1}, &{2});",
-                                tableName, key, value)
-
-    def generateDword(self, serializer):
-        pass
-
-    def serializeCodeSection(self, serializer):
-        pass
-
-    def getIncludes(self):
-        return """
-#include <uapi/linux/bpf.h>
-#include <uapi/linux/if_ether.h>
-#include <uapi/linux/if_packet.h>
-#include <uapi/linux/ip.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/pkt_cls.h>
-"""
-
-    def serializeLicense(self, serializer, licenseString):
-        assert isinstance(serializer, ProgramSerializer)
-        pass
diff --git a/src/cc/frontends/p4/compiler/topoSorting.py b/src/cc/frontends/p4/compiler/topoSorting.py
deleted file mode 100644 (file)
index 21daba3..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2013-present Barefoot Networks, 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.
-#
-
-#
-# Antonin Bas (antonin@barefootnetworks.com)
-#
-#
-
-# -*- coding: utf-8 -*-
-
-from __future__ import print_function
-
-class Node(object):
-    def __init__(self, n):
-        self.n = n
-        self.edges = set()
-
-    def add_edge_to(self, other):
-        assert(isinstance(other, Node))
-        self.edges.add(other)
-
-    def __str__(self):
-        return str(self.n)
-
-
-class Graph(object):
-    def __init__(self):
-        self.nodes = {}
-        self.root = None
-
-    def add_node(self, node):
-        assert(node not in self.nodes)
-        self.nodes[node] = Node(node)
-
-    def __contains__(self, node):
-        return node in self.nodes
-
-    def get_node(self, node):
-        return self.nodes[node]
-
-    def produce_topo_sorting(self):
-        def visit(node, topo_sorting, sequence=None):
-            if sequence is not None:
-                sequence += [str(node)]
-            if node._behavioral_topo_sorting_mark == 1:
-                if sequence is not None:
-                    print("cycle", sequence)
-                return False
-            if node._behavioral_topo_sorting_mark != 2:
-                node._behavioral_topo_sorting_mark = 1
-                for next_node in node.edges:
-                    res = visit(next_node, topo_sorting, sequence)
-                    if not res:
-                        return False
-                node._behavioral_topo_sorting_mark = 2
-                topo_sorting.insert(0, node.n)
-            return True
-
-        has_cycle = False
-        topo_sorting = []
-
-        for node in self.nodes.values():
-            # 0 is unmarked, 1 is temp, 2 is permanent
-            node._behavioral_topo_sorting_mark = 0
-        for node in self.nodes.values():
-            if node._behavioral_topo_sorting_mark == 0:
-                if not visit(node, topo_sorting, sequence=[]):
-                    has_cycle = True
-                    break
-        # removing mark
-        for node in self.nodes.values():
-            del node._behavioral_topo_sorting_mark
-
-        if has_cycle:
-            return None
-
-        return topo_sorting
diff --git a/src/cc/frontends/p4/compiler/typeFactory.py b/src/cc/frontends/p4/compiler/typeFactory.py
deleted file mode 100644 (file)
index 71a0207..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-from p4_hlir.hlir import p4_header
-from ebpfStructType import *
-
-class EbpfTypeFactory(object):
-    def __init__(self, config):
-        self.type_map = {}
-        self.config = config
-
-    def build(self, hlirType, asMetadata):
-        name = hlirType.name
-        if hlirType.name in self.type_map:
-            retval = self.type_map[name]
-            if ((not asMetadata and isinstance(retval, EbpfMetadataType)) or
-                (asMetadata and isinstance(retval, EbpfHeaderType))):
-                raise CompilationException(
-                    True, "Same type used both as a header and metadata {0}",
-                    hlirType)
-
-        if isinstance(hlirType, p4_header):
-            if asMetadata:
-                type = EbpfMetadataType(hlirType, self.config)
-            else:
-                type = EbpfHeaderType(hlirType, self.config)
-        else:
-            raise CompilationException(True, "Unexpected type {0}", hlirType)
-        self.registerType(name, type)
-        return type
-
-    def registerType(self, name, ebpfType):
-        self.type_map[name] = ebpfType
diff --git a/src/cc/frontends/p4/docs/README.md b/src/cc/frontends/p4/docs/README.md
deleted file mode 100644 (file)
index 5f94933..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# External references
-
-See [p4toEbpf-bcc.pdf](https://github.com/iovisor/bpf-docs/blob/master/p4/p4toEbpf-bcc.pdf)
diff --git a/src/cc/frontends/p4/scope.png b/src/cc/frontends/p4/scope.png
deleted file mode 100644 (file)
index 585f8cf..0000000
Binary files a/src/cc/frontends/p4/scope.png and /dev/null differ
diff --git a/src/cc/frontends/p4/test/README.txt b/src/cc/frontends/p4/test/README.txt
deleted file mode 100644 (file)
index 9aace16..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-This folder contains tests for the P4->C->EBPF compiler
-
-- cleanup.sh should be run if for some reason endToEndTest.py crashes
-  and leaves garbage namespaces or links
-
-- testP4toEbpf.py compiles all P4 files in the testprograms folder and
-  deposits the corresponding C files in the testoutputs folder
-
-- endToEndTest.py runs a complete end-to-end test compiling the
-  testprograms/simple.p4 program, creating a virtual network with 3
-  boxes (using network namespaces): client, server, switch, loading
-  the EBPF into the kernel of the switch box using the TC, and
-  implementing the forwarding in the switch solely using the P4
-  program.
-  
-  
diff --git a/src/cc/frontends/p4/test/cleanup.sh b/src/cc/frontends/p4/test/cleanup.sh
deleted file mode 100755 (executable)
index 0c14387..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-# Run this script if for some reason the endToEndTest.py crashed
-# and left some garbage state
-
-ip netns del sw
-ip netns del srv
-ip netns del clt
-
-ip link del dev veth-clt-sw
-ip link del dev veth-srv-sw
-
diff --git a/src/cc/frontends/p4/test/endToEndTest.py b/src/cc/frontends/p4/test/endToEndTest.py
deleted file mode 100755 (executable)
index 1133719..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-# Testing example for P4->EBPF compiler
-#
-# This program exercises the simple.c EBPF program
-# generated from the simple.p4 source file.
-
-from __future__ import print_function
-import subprocess
-import ctypes
-import time
-import sys
-import os
-from bcc import BPF
-from pyroute2 import IPRoute, NSPopen, NetNS
-from netaddr import IPAddress
-
-### This part is a simple generic network simulaton toolkit
-
-class Base(object):
-    def __init__(self):
-        self.verbose = True
-
-    def message(self, *args):
-        if self.verbose:
-            print(*args)
-
-
-class Endpoint(Base):
-    # a network interface really
-    def __init__(self, ipaddress, ethaddress):
-        Base.__init__(self)
-        self.mac_addr = ethaddress
-        self.ipaddress = ipaddress
-        self.prefixlen = 24
-        self.parent = None
-
-    def __str__(self):
-        return "Endpoint " + str(self.ipaddress)
-
-    def set_parent(self, parent):
-        assert isinstance(parent, Node)
-        self.parent = parent
-
-    def get_ip_address(self):
-        return IPAddress(self.ipaddress)
-
-
-class Node(Base):
-    # Used to represent one of clt, sw, srv
-    # Each lives in its own namespace
-    def __init__(self, name):
-        Base.__init__(self)
-        self.name = name
-        self.endpoints = []
-        self.get_ns()  # as a side-effect creates namespace
-
-    def add_endpoint(self, endpoint):
-        assert isinstance(endpoint, Endpoint)
-        self.endpoints.append(endpoint)
-        endpoint.set_parent(self)
-
-    def __str__(self):
-        return "Node " + self.name
-
-    def get_ns_name(self):
-        return self.name
-
-    def get_ns(self):
-        nsname = self.get_ns_name()
-        ns = NetNS(nsname)
-        return ns
-
-    def remove(self):
-        ns = self.get_ns();
-        ns.close()
-        ns.remove()
-
-    def execute(self, command):
-        # Run a command in the node's namespace
-        # Return the command's exit code
-        self.message(self.name, "Executing", command)
-        nsn = self.get_ns_name()
-        pipe = NSPopen(nsn, command)
-        result = pipe.wait()
-        pipe.release()
-        return result
-
-    def set_arp(self, destination):
-        assert isinstance(destination, Endpoint)
-        command = ["arp", "-s", str(destination.ipaddress),
-                   str(destination.mac_addr)]
-        self.execute(command)
-
-
-class NetworkBase(Base):
-    def __init__(self):
-        Base.__init__(self)
-        self.ipr = IPRoute()
-        self.nodes = []
-
-    def add_node(self, node):
-        assert isinstance(node, Node)
-        self.nodes.append(node)
-
-    def get_interface_name(self, source, dest):
-        assert isinstance(source, Node)
-        assert isinstance(dest, Node)
-        interface_name = "veth-" + source.name + "-" + dest.name
-        return interface_name
-
-    def get_interface(self, ifname):
-        interfaces = self.ipr.link_lookup(ifname=ifname)
-        if len(interfaces) != 1:
-            raise Exception("Could not identify interface " + ifname)
-        ix = interfaces[0]
-        assert isinstance(ix, int)
-        return ix
-
-    def set_interface_ipaddress(self, node, ifname, address, mask):
-        # Ask a node to set the specified interface address
-        if address is None:
-            return
-
-        assert isinstance(node, Node)
-        command = ["ip", "addr", "add", str(address) + "/" + str(mask),
-                   "dev", str(ifname)]
-        result = node.execute(command)
-        assert(result == 0)
-
-    def create_link(self, src, dest):
-        assert isinstance(src, Endpoint)
-        assert isinstance(dest, Endpoint)
-
-        ifname = self.get_interface_name(src.parent, dest.parent)
-        destname = self.get_interface_name(dest.parent, src.parent)
-        self.ipr.link_create(ifname=ifname, kind="veth", peer=destname)
-
-        self.message("Create", ifname, "link")
-
-        # Set source endpoint information
-        ix = self.get_interface(ifname)
-        self.ipr.link("set", index=ix, address=src.mac_addr)
-        # push source endpoint into source namespace
-        self.ipr.link("set", index=ix,
-                      net_ns_fd=src.parent.get_ns_name(), state="up")
-        # Set interface ip address; seems to be
-        # lost of set prior to moving to namespace
-        self.set_interface_ipaddress(
-            src.parent, ifname, src.ipaddress , src.prefixlen)
-
-        # Sef destination endpoint information
-        ix = self.get_interface(destname)
-        self.ipr.link("set", index=ix, address=dest.mac_addr)
-        # push destination endpoint into the destination namespace
-        self.ipr.link("set", index=ix,
-                      net_ns_fd=dest.parent.get_ns_name(), state="up")
-        # Set interface ip address
-        self.set_interface_ipaddress(dest.parent, destname,
-                                     dest.ipaddress, dest.prefixlen)
-
-    def show_interfaces(self, node):
-        cmd = ["ip", "addr"]
-        if node is None:
-            # Run with no namespace
-            subprocess.call(cmd)
-        else:
-            # Run in node's namespace
-            assert isinstance(node, Node)
-            self.message("Enumerating all interfaces in ", node.name)
-            node.execute(cmd)
-
-    def delete(self):
-        self.message("Deleting virtual network")
-        for n in self.nodes:
-            n.remove()
-        self.ipr.close()
-
-
-### Here begins the concrete instantiation of the network
-# Network setup:
-# Each of these is a separate namespace.
-#
-#                        62:ce:1b:48:3e:61          a2:59:94:cf:51:09
-#      96:a4:85:fe:2a:11           62:ce:1b:48:3e:60
-#              /------------------\     /-----------------\
-#      ----------                 --------                ---------
-#      |  clt   |                 |  sw  |                |  srv  |
-#      ----------                 --------                ---------
-#       10.0.0.11                                         10.0.0.10
-#
-
-class SimulatedNetwork(NetworkBase):
-    def __init__(self):
-        NetworkBase.__init__(self)
-
-        self.client = Node("clt")
-        self.add_node(self.client)
-        self.client_endpoint = Endpoint("10.0.0.11", "96:a4:85:fe:2a:11")
-        self.client.add_endpoint(self.client_endpoint)
-
-        self.server = Node("srv")
-        self.add_node(self.server)
-        self.server_endpoint = Endpoint("10.0.0.10", "a2:59:94:cf:51:09")
-        self.server.add_endpoint(self.server_endpoint)
-
-        self.switch = Node("sw")
-        self.add_node(self.switch)
-        self.sw_clt_endpoint = Endpoint(None, "62:ce:1b:48:3e:61")
-        self.sw_srv_endpoint = Endpoint(None, "62:ce:1b:48:3e:60")
-        self.switch.add_endpoint(self.sw_clt_endpoint)
-        self.switch.add_endpoint(self.sw_srv_endpoint)
-
-    def run_method_in_node(self, node, method, args):
-        # run a method of the SimulatedNetwork class in a different namespace
-        # return the exit code
-        assert isinstance(node, Node)
-        assert isinstance(args, list)
-        torun = __file__
-        args.insert(0, torun)
-        args.insert(1, method)
-        return node.execute(args)  # runs the command argv[0] method args
-
-    def instantiate(self):
-        # Creates the various namespaces
-        self.message("Creating virtual network")
-
-        self.message("Create client-switch link")
-        self.create_link(self.client_endpoint, self.sw_clt_endpoint)
-
-        self.message("Create server-switch link")
-        self.create_link(self.server_endpoint, self.sw_srv_endpoint)
-
-        self.show_interfaces(self.client)
-        self.show_interfaces(self.server)
-        self.show_interfaces(self.switch)
-
-        self.message("Set ARP mappings")
-        self.client.set_arp(self.server_endpoint)
-        self.server.set_arp(self.client_endpoint)
-
-    def setup_switch(self):
-        # This method is run in the switch namespace.
-        self.message("Compiling and loading BPF program")
-
-        b = BPF(src_file="./simple.c", debug=0)
-        fn = b.load_func("ebpf_filter", BPF.SCHED_CLS)
-
-        self.message("BPF program loaded")
-
-        self.message("Discovering tables")
-        routing_tbl = b.get_table("routing")
-        routing_miss_tbl = b.get_table("ebpf_routing_miss")
-        cnt_tbl = b.get_table("cnt")
-
-        self.message("Hooking up BPF classifiers using TC")
-
-        interfname = self.get_interface_name(self.switch, self.server)
-        sw_srv_idx = self.get_interface(interfname)
-        self.ipr.tc("add", "ingress", sw_srv_idx, "ffff:")
-        self.ipr.tc("add-filter", "bpf", sw_srv_idx, ":1", fd=fn.fd,
-                    name=fn.name, parent="ffff:", action="ok", classid=1)
-
-        interfname = self.get_interface_name(self.switch, self.client)
-        sw_clt_idx = self.get_interface(interfname)
-        self.ipr.tc("add", "ingress", sw_clt_idx, "ffff:")
-        self.ipr.tc("add-filter", "bpf", sw_clt_idx, ":1", fd=fn.fd,
-                    name=fn.name, parent="ffff:", action="ok", classid=1)
-
-        self.message("Populating tables from the control plane")
-        cltip = self.client_endpoint.get_ip_address()
-        srvip = self.server_endpoint.get_ip_address()
-
-        # BCC does not support tbl.Leaf when the type contains a union,
-        # so we have to make up the value type manually.  Unfortunately
-        # these sizes are not portable...
-
-        class Forward(ctypes.Structure):
-            _fields_ = [("port", ctypes.c_ushort)]
-
-        class Nop(ctypes.Structure):
-            _fields_ = []
-
-        class Union(ctypes.Union):
-            _fields_ = [("nop", Nop),
-                        ("forward", Forward)]
-
-        class Value(ctypes.Structure):
-            _fields_ = [("action", ctypes.c_uint),
-                        ("u", Union)]
-
-        if False:
-            # This is how it should ideally be done, but it does not work
-            routing_tbl[routing_tbl.Key(int(cltip))] = routing_tbl.Leaf(
-                1, sw_clt_idx)
-            routing_tbl[routing_tbl.Key(int(srvip))] = routing_tbl.Leaf(
-                1, sw_srv_idx)
-        else:
-            v1 = Value()
-            v1.action = 1
-            v1.u.forward.port = sw_clt_idx
-
-            v2 = Value()
-            v2.action = 1;
-            v2.u.forward.port = sw_srv_idx
-
-            routing_tbl[routing_tbl.Key(int(cltip))] = v1
-            routing_tbl[routing_tbl.Key(int(srvip))] = v2
-
-        self.message("Dumping table contents")
-        for key, leaf in routing_tbl.items():
-            self.message(str(IPAddress(key.key_field_0)),
-                         leaf.action, leaf.u.forward.port)
-
-    def run(self):
-        self.message("Pinging server from client")
-        ping = ["ping", self.server_endpoint.ipaddress, "-c", "2"]
-        result = self.client.execute(ping)
-        if result != 0:
-            raise Exception("Test failed")
-        else:
-            print("Test succeeded!")
-
-    def prepare_switch(self):
-        self.message("Configuring switch")
-        # Re-invokes this script in the switch namespace;
-        # this causes the setup_switch method to be run in that context.
-        # This is the same as running self.setup_switch()
-        # but in the switch namespace
-        self.run_method_in_node(self.switch, "setup_switch", [])
-
-
-def compile(source, destination):
-    try:
-        status = subprocess.call(
-            "../compiler/p4toEbpf.py " + source + " -o " + destination,
-            shell=True)
-        if status < 0:
-            print("Child was terminated by signal", -status, file=sys.stderr)
-        else:
-            print("Child returned", status, file=sys.stderr)
-    except OSError as e:
-        print("Execution failed:", e, file=sys.stderr)
-        raise e
-
-def start_simulation():
-    compile("testprograms/simple.p4", "simple.c")
-    network = SimulatedNetwork()
-    network.instantiate()
-    network.prepare_switch()
-    network.run()
-    network.delete()
-    os.remove("simple.c")
-
-def main(argv):
-    print(str(argv))
-    if len(argv) == 1:
-        # Main entry point: start simulation
-        start_simulation()
-    else:
-        # We are invoked with some arguments (probably in a different namespace)
-        # First argument is a method name, rest are method arguments.
-        # Create a SimulatedNetwork and invoke the specified method with the
-        # specified arguments.
-        network = SimulatedNetwork()
-        methodname = argv[1]
-        arguments = argv[2:]
-        method = getattr(network, methodname)
-        method(*arguments)
-
-if __name__ == '__main__':
-    main(sys.argv)
-
diff --git a/src/cc/frontends/p4/test/testP4toEbpf.py b/src/cc/frontends/p4/test/testP4toEbpf.py
deleted file mode 100755 (executable)
index 5406f59..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) Barefoot Networks, Inc.
-# Licensed under the Apache License, Version 2.0 (the "License")
-
-# Runs the compiler on all files in the 'testprograms' folder
-# Writes outputs in the 'testoutputs' folder
-
-from __future__ import print_function
-from bcc import BPF
-import os, sys
-sys.path.append("../compiler") # To get hold of p4toEbpf
-                               # We want to run it without installing it
-import p4toEbpf
-import os
-
-def drop_extension(filename):
-    return os.path.splitext(os.path.basename(filename))[0]
-
-filesFailed = {}  # map error kind -> list[ (file, error) ]
-
-def set_error(kind, file, error):
-    if kind in filesFailed:
-        filesFailed[kind].append((file, error))
-    else:
-        filesFailed[kind] = [(file, error)]
-
-def is_root():
-    # Is this code portable?
-    return os.getuid() == 0
-
-def main():
-    testpath = "testprograms"
-    destFolder = "testoutputs"
-    files = os.listdir(testpath)
-    files.sort()
-    filesDone = 0
-    errors = 0
-
-    if not is_root():
-        print("Loading EBPF programs requires root privilege.")
-        print("Will only test compilation, not loading.")
-        print("(Run with sudo to test program loading.)")
-
-    for f in files:
-        path = os.path.join(testpath, f)
-
-        if not os.path.isfile(path):
-            continue
-        if not path.endswith(".p4"):
-            continue
-
-        destname = drop_extension(path) + ".c"
-        destname = os.path.join(destFolder, destname)
-
-        args = [path, "-o", destname]
-
-        result = p4toEbpf.process(args)
-        if result.kind != "OK":
-            errors += 1
-            print(path, result.error)
-            set_error(result.kind, path, result.error)
-        else:
-            # Try to load the compiled function
-            if is_root():
-                try:
-                    print("Compiling and loading BPF program")
-                    b = BPF(src_file=destname, debug=0)
-                    fn = b.load_func("ebpf_filter", BPF.SCHED_CLS)
-                except Exception as e:
-                    print(e)
-                    set_error("BPF error", path, str(e))
-
-        filesDone += 1
-
-    print("Compiled", filesDone, "files", errors, "errors")
-    for key in sorted(filesFailed):
-        print(key, ":", len(filesFailed[key]), "programs")
-        for v in filesFailed[key]:
-            print("\t", v)
-    exit(len(filesFailed) != 0)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/src/cc/frontends/p4/test/testoutputs/.empty b/src/cc/frontends/p4/test/testoutputs/.empty
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/cc/frontends/p4/test/testprograms/arrayKey.p4 b/src/cc/frontends/p4/test/testprograms/arrayKey.p4
deleted file mode 100644 (file)
index cc6f028..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-header_type ethernet_t {
-    fields {
-        dstAddr : 48;
-        srcAddr : 48;
-        etherType : 16;
-    }
-}
-
-parser start {
-    return parse_ethernet;
-}
-
-header ethernet_t ethernet;
-
-parser parse_ethernet {
-    extract(ethernet);
-    return ingress;
-}
-
-action nop() 
-{}
-
-table routing {
-   reads {
-      ethernet.dstAddr: exact;
-   }
-   actions { nop; }
-   size : 512;
-}
-
-control ingress
-{
-    apply(routing);
-}
\ No newline at end of file
diff --git a/src/cc/frontends/p4/test/testprograms/basic_routing.p4 b/src/cc/frontends/p4/test/testprograms/basic_routing.p4
deleted file mode 100644 (file)
index 5644071..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
-Copyright 2013-present Barefoot Networks, 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.
-*/
-
-header_type ethernet_t {
-    fields {
-        dstAddr : 48;
-        srcAddr : 48;
-        etherType : 16;
-    }
-}
-
-header_type ipv4_t {
-    fields {
-        version : 4;
-        ihl : 4;
-        diffserv : 8;
-        totalLen : 16;
-        identification : 16;
-        flags : 3;
-        fragOffset : 13;
-        ttl : 8;
-        protocol : 8;
-        hdrChecksum : 16;
-        srcAddr : 32;
-        dstAddr: 32;
-    }
-}
-
-parser start {
-    return parse_ethernet;
-}
-
-#define ETHERTYPE_IPV4 0x0800
-
-header ethernet_t ethernet;
-
-parser parse_ethernet {
-    extract(ethernet);
-    return select(latest.etherType) {
-        ETHERTYPE_IPV4 : parse_ipv4;
-        default: ingress;
-    }
-}
-
-header ipv4_t ipv4;
-
-/* Not yet supported on EBPF target
-
-field_list ipv4_checksum_list {
-        ipv4.version;
-        ipv4.ihl;
-        ipv4.diffserv;
-        ipv4.totalLen;
-        ipv4.identification;
-        ipv4.flags;
-        ipv4.fragOffset;
-        ipv4.ttl;
-        ipv4.protocol;
-        ipv4.srcAddr;
-        ipv4.dstAddr;
-}
-
-field_list_calculation ipv4_checksum {
-    input {
-        ipv4_checksum_list;
-    }
-    algorithm : csum16;
-    output_width : 16;
-}
-
-calculated_field ipv4.hdrChecksum  {
-    verify ipv4_checksum;
-    update ipv4_checksum;
-}
-*/
-
-parser parse_ipv4 {
-    extract(ipv4);
-    return ingress;
-}
-
-#define PORT_VLAN_TABLE_SIZE                   32768
-#define BD_TABLE_SIZE                          65536
-#define IPV4_LPM_TABLE_SIZE                    16384
-#define IPV4_HOST_TABLE_SIZE                   131072
-#define NEXTHOP_TABLE_SIZE                     32768
-#define REWRITE_MAC_TABLE_SIZE                 32768
-
-#define VRF_BIT_WIDTH                          12
-#define BD_BIT_WIDTH                           16
-#define IFINDEX_BIT_WIDTH                      10
-
-/* METADATA */
-header_type ingress_metadata_t {
-    fields {
-        vrf : VRF_BIT_WIDTH;                   /* VRF */
-        bd : BD_BIT_WIDTH;                     /* ingress BD */
-        nexthop_index : 16;                    /* final next hop index */
-    }
-}
-
-metadata ingress_metadata_t ingress_metadata;
-
-action on_miss() {
-}
-
-action set_bd(bd) {
-    modify_field(ingress_metadata.bd, bd);
-}
-
-table port_mapping {
-    reads {
-        standard_metadata.ingress_port : exact;
-    }
-    actions {
-        set_bd;
-    }
-    size : PORT_VLAN_TABLE_SIZE;
-}
-
-action set_vrf(vrf) {
-    modify_field(ingress_metadata.vrf, vrf);
-}
-
-table bd {
-    reads {
-        ingress_metadata.bd : exact;
-    }
-    actions {
-        set_vrf;
-    }
-    size : BD_TABLE_SIZE;
-}
-
-action fib_hit_nexthop(nexthop_index) {
-    modify_field(ingress_metadata.nexthop_index, nexthop_index);
-    subtract_from_field(ipv4.ttl, 1);
-}
-
-table ipv4_fib {
-    reads {
-        ingress_metadata.vrf : exact;
-        ipv4.dstAddr : exact;
-    }
-    actions {
-        on_miss;
-        fib_hit_nexthop;
-    }
-    size : IPV4_HOST_TABLE_SIZE;
-}
-
-table ipv4_fib_lpm {
-    reads {
-        ingress_metadata.vrf : exact;
-        ipv4.dstAddr : exact; // lpm not supported
-    }
-    actions {
-        on_miss;
-        fib_hit_nexthop;
-    }
-    size : IPV4_LPM_TABLE_SIZE;
-}
-
-action set_egress_details(egress_spec) {
-    modify_field(standard_metadata.egress_spec, egress_spec);
-}
-
-table nexthop {
-    reads {
-        ingress_metadata.nexthop_index : exact;
-    }
-    actions {
-        on_miss;
-        set_egress_details;
-    }
-    size : NEXTHOP_TABLE_SIZE;
-}
-
-control ingress {
-    if (valid(ipv4)) {
-        /* derive ingress_metadata.bd */
-        apply(port_mapping);
-
-        /* derive ingress_metadata.vrf */
-        apply(bd);
-
-        /* fib lookup, set ingress_metadata.nexthop_index */
-        apply(ipv4_fib) {
-            on_miss {
-                apply(ipv4_fib_lpm);
-            }
-        }
-
-        /* derive standard_metadata.egress_spec from ingress_metadata.nexthop_index */
-        apply(nexthop);
-    }
-}
-
-action rewrite_src_dst_mac(smac, dmac) {
-    modify_field(ethernet.srcAddr, smac);
-    modify_field(ethernet.dstAddr, dmac);
-}
-
-table rewrite_mac {
-    reads {
-        ingress_metadata.nexthop_index : exact;
-    }
-    actions {
-        on_miss;
-        rewrite_src_dst_mac;
-    }
-    size : REWRITE_MAC_TABLE_SIZE;
-}
-
-control egress {
-    /* set smac and dmac from ingress_metadata.nexthop_index */
-    apply(rewrite_mac);
-}
\ No newline at end of file
diff --git a/src/cc/frontends/p4/test/testprograms/bitfields.p4 b/src/cc/frontends/p4/test/testprograms/bitfields.p4
deleted file mode 100644 (file)
index 9123c49..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-header_type ht
-{
-  fields
-  {
-     f1 : 1;
-     f2 : 2;
-     f3 : 3;
-     f4 : 4;
-     f5 : 5;
-     f6 : 6;
-     f7 : 7;
-     f8 : 8;
-     f9 : 9;
-     f10 : 10;
-     f11 : 11;
-     f12 : 12;
-     f13 : 13;
-     f14 : 14;
-     f15 : 15;
-     f16 : 16;
-     f17 : 17;
-     f18 : 18;
-     f19 : 19;
-     f20 : 20;
-     f21 : 21;
-     f22 : 22;
-     f23 : 23;
-     f24 : 24;
-     f25 : 25;
-     f26 : 26;
-     f27 : 27;
-     f28 : 28;
-     f29 : 29;
-     f30 : 30;
-     f31 : 31;
-     f32 : 32;
-  }
-}
-
-header_type larget
-{
-  fields 
-  {
-    f48 : 48;
-    f1: 1;
-    f49 : 48;
-    f2 : 1;
-    f64 : 64;
-    f3 : 1;
-    f128 : 128;
-  }
-}
-
-header ht h;
-header larget large;
-
-parser start
-{
-       extract(h);
-       extract(large);
-       return ingress;
-}
-
-control ingress
-{
-}
diff --git a/src/cc/frontends/p4/test/testprograms/compositeArray.p4 b/src/cc/frontends/p4/test/testprograms/compositeArray.p4
deleted file mode 100644 (file)
index 5524042..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-header_type ethernet_t {
-    fields {
-        dstAddr : 48;
-    }
-}
-
-header_type ipv4_t {
-    fields {
-        srcAddr : 32;
-    }
-}
-
-parser start {
-    return parse_ethernet;
-}
-
-header ethernet_t ethernet;
-
-parser parse_ethernet {
-    extract(ethernet);
-    return parse_ipv4;
-}
-
-action nop() 
-{}
-
-header ipv4_t ipv4;
-
-parser parse_ipv4 {
-    extract(ipv4);
-    return ingress;
-}
-
-table routing {
-   reads {
-      ethernet.dstAddr: exact;
-      ipv4.srcAddr: exact;
-   }
-   actions { nop; }
-   size : 512;
-}
-
-control ingress
-{
-    apply(routing);
-}
\ No newline at end of file
diff --git a/src/cc/frontends/p4/test/testprograms/compositeKey.p4 b/src/cc/frontends/p4/test/testprograms/compositeKey.p4
deleted file mode 100644 (file)
index ed04e9f..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-header_type ethernet_t {
-    fields {
-        dstAddr : 48;
-        srcAddr : 48;
-        etherType : 16;
-    }
-}
-
-header_type ipv4_t {
-    fields {
-        version : 4;
-        ihl : 4;
-        diffserv : 8;
-        totalLen : 16;
-        identification : 16;
-        flags : 3;
-        fragOffset : 13;
-        ttl : 8;
-        protocol : 8;
-        hdrChecksum : 16;
-        srcAddr : 32;
-        dstAddr: 32;
-    }
-}
-
-parser start {
-    return parse_ethernet;
-}
-
-header ethernet_t ethernet;
-
-parser parse_ethernet {
-    extract(ethernet);
-    return select(latest.etherType) {
-        0x800 : parse_ipv4;
-        default: ingress;
-    }
-}
-
-action nop() 
-{}
-
-action forward(port)
-{
-   modify_field(standard_metadata.egress_port, port);
-}
-
-header ipv4_t ipv4;
-
-parser parse_ipv4 {
-    extract(ipv4);
-    return ingress;
-}
-
-table routing {
-   reads {
-      ipv4.dstAddr: exact;
-      ipv4.srcAddr: exact;
-   }
-   actions { nop; forward; }
-   size : 512;
-}
-
-counter cnt {
-   type: bytes;
-   direct: routing;
-}
-
-control ingress
-{
-    apply(routing);
-}
\ No newline at end of file
diff --git a/src/cc/frontends/p4/test/testprograms/do_nothing.p4 b/src/cc/frontends/p4/test/testprograms/do_nothing.p4
deleted file mode 100644 (file)
index 845f8d4..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Sample P4 program */
-header_type ethernet_t {
-    fields {
-        dstAddr : 48;
-        srcAddr : 48;
-        etherType : 16;
-    }
-}
-
-parser start {
-    return parse_ethernet;
-}
-
-header ethernet_t ethernet;
-
-parser parse_ethernet {
-    extract(ethernet);
-    return ingress;
-}
-
-action action_0(){
-    no_op();
-}
-
-table table_0 {
-   reads {
-      ethernet.etherType : exact;
-   }
-   actions {
-      action_0;
-   }
-}
-
-control ingress {
-    apply(table_0);
-}
diff --git a/src/cc/frontends/p4/test/testprograms/simple.p4 b/src/cc/frontends/p4/test/testprograms/simple.p4
deleted file mode 100644 (file)
index 7f28561..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Routes a packet to an interface based on its IPv4 address
-// Maintains a set of counters on the routing table
-
-header_type ethernet_t {
-    fields {
-        dstAddr : 48;
-        srcAddr : 48;
-        etherType : 16;
-    }
-}
-
-header_type ipv4_t {
-    fields {
-        version : 4;
-        ihl : 4;
-        diffserv : 8;
-        totalLen : 16;
-        identification : 16;
-        flags : 3;
-        fragOffset : 13;
-        ttl : 8;
-        protocol : 8;
-        hdrChecksum : 16;
-        srcAddr : 32;
-        dstAddr: 32;
-    }
-}
-
-parser start {
-    return parse_ethernet;
-}
-
-header ethernet_t ethernet;
-
-parser parse_ethernet {
-    extract(ethernet);
-    return select(latest.etherType) {
-        0x800 : parse_ipv4;
-        default: ingress;
-    }
-}
-
-action nop() 
-{}
-
-action forward(port)
-{
-   modify_field(standard_metadata.egress_port, port);
-}
-
-header ipv4_t ipv4;
-
-parser parse_ipv4 {
-    extract(ipv4);
-    return ingress;
-}
-
-table routing {
-   reads {
-      ipv4.dstAddr: exact;
-   }
-   actions { nop; forward; }
-   size : 512;
-}
-
-counter cnt {
-   type: bytes;
-   direct: routing;
-}
-
-control ingress
-{
-    apply(routing);
-}
\ No newline at end of file