Skip to content

Obtain all possible outputs generated by ActionSelector group members with single input packet #1312

@Hoooao

Description

@Hoooao

ActionSelector helps to define a mapping from table keys to action groups, and uses a designated hash algorithm to choose one action member from the matched group.

This issue tries to propose a way to have all the members of a matched group be applied and obtain the set of output results for analysis.

Having all members in a matched group applied is beneficial for several reasons. One of them is diff testing, where we use BMv2 to check the validity of the deployed ActionSelector behaviors.

There are 2 approaches:

  • Concolic Testing: use constraint solvers to generate concrete test cases that go through all the paths created by selectors.
  • A new replication engine: for a given selector, replicate N packet headers where N is the number of members of the matched group. Reassemble the headers and "resubmit" them to the gress that the selector resides in, but we have them starting from the control flow node (table) they get replicated.

We choose the second one by instrumenting the BMv2 source code instead of making an automated tool following the first approach for 3 reasons:

  • Instrumenting the code is much simpler and localized to a few components of BMv2.
  • Hash introduces challenges to solvers: solving for an input is non-trivial when the hash algorithm is complex.
  • Performance could be an issue for the solver as the number of possible outputs grows exponentially as the number of selectors increases.

Here is an overview of how it works (we focus on ingress for now):

Image
  1. When a header reaches a selector, it will be replicated N times, where N is (the number of members in the matched group - 1).
  2. The original header will be processed as usual. For each replicated header, the next_table after applying its specific action will be associated with it. They will be stored in a singleton vector.
  3. Then the replicated headers will be reassembled using deparser and pushed to the ingress buffer with the highest priority.
  4. One by one, they are pushed to the parser as if they are new input headers.
  5. Upon getting processed by the pipeline, the next_table will be used as the starting control flow node(table), instead of starting from the initial table defined in the program.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions