Giter Site home page Giter Site logo

tdi's Introduction

TDI

Introduction

TDI (Table Driven Interface) is a Target Abstraction Interface. It is a set of APIs that enable configuration and management of P4 programmable and fixed functions of a backend device in a uniform and dynamic way.

Different targets like bmv2, P4-DPDK can choose to implement their own backends for different P4 and non-P4 objects but can share a common TDI. TDI uses JSON formatted data to describe the tables and other objects of the interface, TDI requires this to be present in a file named tdi.json. This json defines multiple Table and Learn objects.

P4 Architecture and its role in TDI

TDI code is divided into 3 layers

  • Core : This is the common layer. Code under src directly and code under include/common refers to core code. This includes anything that is not dependent on P4 architecture or target specifications. Match Types - Exact, Ternary, and LPM are all part of the core layer since they are defined by the P4-16 language.
  • Arch : The Arch dependent code. This would contain any code that is dependent on the P4 target's architecture. For example, Tofino Native Architecture (TNA) specific code for Idletime attributes, Counters, Registers, etc will have Key and Data handling structures here since the schema for these objects depend upon the arch specifications. Targets may choose to use this code or not to use this code by choice of C++ polymorphism or directly inherit from the top level tdi::Table class.
  • Target : This code is target dependent. The code under target in this repository will be present solely as an example through a dummy target. Device implementors are expected to have their own backends just like the dummy_target.

Properties of TDI

All P4 programmable objects and non-P4 programmable objects are realized via "table" structures. A table consists of the below

  • Key
  • Actions
  • Data
  • Attributes
  • Operations

For a P4 match table

    table forward {
        key = {
            hdr.ethernet.dst_addr : exact;
        }
        actions = {
            hit;
            @defaultonly miss;
        }
        const default_action = miss(0x1);
        size = 1024;
    }

tdi.json structure could look like the below.

    {
      "name" : "pipe.SwitchIngress.forward",
      "id" : 37882547,
      "table_type" : "MatchAction_Direct",
      "size" : 1024,
      "has_const_default_action" : true,
      "key" : [
        {
          "id" : 1,
          "name" : "hdr.ethernet.dst_addr",
          "repeated" : false,,
          "match_type" : "Exact",
          "type" : {
            "type" : "bytes",
            "width" : 48
          }
        }
      ],
      "action_specs" : [
        {
          "id" : 32848556,
          "name" : "SwitchIngress.hit",
          "data" : [
            {
              "id" : 1,
              "name" : "port",
              "repeated" : false,
              "type" : {
                "type" : "bytes",
                "width" : 9
              }
            }
          ]
        },
        {
          "id" : 17988458,
          "name" : "SwitchIngress.miss",
          "data" : [
            {
              "id" : 1,
              "name" : "drop",
              "repeated" : false,
              "type" : {
                "type" : "bytes",
                "width" : 3
              }
            }
          ]
        }
      ],
      "data" : [],
      "supported_operations" : [],
      "attributes" : ["EntryScope"]
    },

Key

Key uniquely defines an entry in the table. A key comprises of several "fields". Tables can be present without any Key in their schema. In such a case, only one entry can reside in the table called as the Default entry and the table is called a Keyless table.

Action

An Action groups together related sets of data fields. At one time, only one action can be active. Tables can be present without any actions too.

Data

Data fields present outside of any actions are called "common" data. They belong to all actions.

Attributes

Attributes are table-wide properties of tables. These define a stateful property of a table, for example, using entry scope attribute in TNA, users can set tables as symmetric or asymmetric and defines the way entries would be programmed in multiple pipeline profiles of a device.

Operations

Operations are also like Attributes. The only difference is that they are one shot and don't change the properties of a table. For example, counter-sync operation in TNA would sync counter values from hardware to software.

TDI APIs Overview

Infrastrcture APIs

APIs to get to a tdi::Table object from a tdi::Device object

Metadata APIs

APIs to query any json information like list of key field IDs, Size, type of fields etc.

Table APIs

CRUD APIs for tables like

  • entryAdd
  • entryDel
  • entryMod
  • clear
  • entryGet
  • entryGetNextN
  • entryGetFirst
  • defaultEntrySet
  • defaultEntryMod
  • defaultEntryGet
  • usageGet

Object allocate/reset APIs like

  • keyAllocate
  • dataAllocate
  • attributeAllocate
  • keyReset

attribute and operations set/get/execute

  • tableAttributeSet
  • tableAttributeGet
  • tableOperationsGet

Session

Session management API to support batching, transactions

  1. The requests made for a session are guaranteed to be executed in order.
  2. Although multiple threads using single session is supported, it's high discouraged as the resource contention creates serialization of the requests.
  3. A single client thread can make requests on multiple sessions for different resources.

TDI multiple program and pipeline support

TDI can support managing multiple devices with multiple programs each and with multiple pipeline profiles if the P4 architecture allows.

Library structure Overview

graph 
A(libtdi) --> B(libtdi_tna)
G(libtarget_utils) --> A
H(libtarget_syslibs) --> A
A --> C(libtdi_pna)
B --> D(libtdi_tofino)
B --> F(libtdi_dummy)
C --> E(libtdi_dpdk)

Build

mkdir -p build && cd build
git submodule update --init --recursive
cmake -DSTANDALONE=ON -DCMAKE_INSTALL_PREFIX=../install .. && make install -j8

tdi's People

Contributors

abhaysi2 avatar abhijit1kale avatar andredl avatar ffoulkes avatar jnfoster avatar nupuruttarwar avatar satish153 avatar saynb avatar sharanakumarpatil avatar swaroopsarma avatar vmytnykx avatar weiqiand avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tdi's Issues

Parenthesis "()" in key field name is not properly handled in tdicli.py

At line number

p_name = name.decode('ascii').replace('$', '').replace('-', '_').replace(':', '_').replace('[', '_').replace(']', '_')
few of the special characters in key name is replaced with appropriate characters such that tdi cli does not throw error (i.e., These key names are used as python method argument identifiers, python identifiers has to be alpha numeric and it cannot contain special characters).
When referred to p4 spec, "isValid()" is also an allowed key name, so this key also has to be handled properly (i.e., replacement for "()")

Error building TDI

Hi,

I'm trying to build TDI but i get this error, do you have any clue to solve it?
Screenshot from 2022-08-08 17-56-04

Standalone build is not working on Fedora 33

Using generic Fedora and Ubuntu envs, building TDI as per the last couple of lines of the README fails with a cmake error. This is in part because the submodules need to be initialized and updated (which should be noted with the build notes). But even after that, cmake reports errors like:

`
-- Looking for inet_network - found
CMake Error at third-party/target-utils/third-party/CMakeLists.txt:45 (add_subdirectory):
The source directory

.../tdi/third-party/target-utils/third-party/cJSON

does not contain a CMakeLists.txt file.

`

and
`
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
EXPAT_LIB
linked by target "clish" in directory .../tdi/third-party/target-utils/third-party/klish
LIBEDIT_LIBRARIES (ADVANCED)
linked by target "clish" in directory .../tdi/third-party/target-utils/third-party/klish

-- Configuring incomplete, errors occurred!

`

Glancing at the CMakeFiles/CMakeErrors.log, maybe it's just some prereq packages that need to be installed? pcap.h, floor, pow, sqrt are mentioned as undefined.

Build instruction in README.md needs update

The current build instruction cmake -DCMAKE_INSTALL_PREFIX=../install .. does not work with latest commit.
Need to use cmake -DSTANDALONE=on -DCMAKE_INSTALL_PREFIX=../install .. instead.

Build artifacts and include files are copied during cmake and make

We have found that during the cmake stage itself all the header files of tdi and its third-party are copied to ${CMAKE_INSTALL_PREFIX}/include/
Few instances here:
https://github.com/p4lang/tdi/blob/22cb07ac887491450d2efdb65cca727f99ecd317/CMakeLists.txt#L15C1-L17C26
https://github.com/p4lang/target-utils/blob/455fc4787a199978e0ae53bd2a6eb0cd2af1b790/CMakeLists.txt#L54

Also during make, libraries are copied to ${CMAKE_INSTALL_PREFIX}/lib. Such as below:
├── libcjson.a
├── libclish.so
├── libtarget_sys.so
├── libtarget_utils.so
├── libtdi_json_parser.so
├── libtdi_pna.so
├── libtdi_psa.so
├── libtdi.so
└── libtdi_tna.so

Is this a standard practice?

From a usability point, these are the following customer requirements we are not able to meet (because of it):

  1. until make install is called the customer wants ${CMAKE_INSTALL_PREFIX} to be untouched.
  2. make uninstall should clean any file copied or created in ${CMAKE_INSTALL_PREFIX}

Probable alternative:
Copy all the libs/artifacts to ${CMAKE_BINARY_DIR} so that we can internally include/link and proceed with the build.
Only "make install" should ideally copy the artifacts.

In this way we can reverse everything done by make install by using make uninstall.

Lot of pylint errors on TDI python code

$ pylint -E tdi_python/tdicli.py
************* Module tdicli
third-party/tdi/tdi_python/tdicli.py:61:4: E0101: Explicit return in init (return-in-init)
third-party/tdi/tdi_python/tdicli.py:260:15: E1101: Class 'value' has no 'decode' member (no-member)
third-party/tdi/tdi_python/tdicli.py:461:27: E1101: Instance of 'TDIContext' has no '_get_children' member (no-member)
third-party/tdi/tdi_python/tdicli.py:467:33: E1101: Instance of 'TDIContext' has no '_parent_node' member (no-member)
third-party/tdi/tdi_python/tdicli.py:474:18: E1101: Instance of 'TDIContext' has no '_parent_node' member (no-member)
third-party/tdi/tdi_python/tdicli.py:815:24: E1101: Instance of 'TDILeaf' has no 'get_default' member (no-member)
third-party/tdi/tdi_python/tdicli.py:906:12: E1111: Assigning result of a function call, where the function has no return (assignment-from-no-return)
third-party/tdi/tdi_python/tdicli.py:906:27: E1120: No value for argument 'type' in function call (no-value-for-parameter)
third-party/tdi/tdi_python/tdicli.py:916:12: E1111: Assigning result of a function call, where the function has no return (assignment-from-no-return)
third-party/tdi/tdi_python/tdicli.py:916:27: E1120: No value for argument 'type' in function call (no-value-for-parameter)
third-party/tdi/tdi_python/tdicli.py:926:12: E1111: Assigning result of a function call, where the function has no return (assignment-from-no-return)
third-party/tdi/tdi_python/tdicli.py:926:27: E1120: No value for argument 'type' in function call (no-value-for-parameter)
third-party/tdi/tdi_python/tdicli.py:2278:20: E1101: Instance of 'TdiCli' has no 'cIntf_cls' member (no-member)

info() command available inside table returning incorrect PIPE info details

From the application though I passed the pipe=1 to the INFO command that is available inside the table run from the PIPE-0, it returning the PIPE-0 table information instead of PIPE-1 table information.

The expectation is: It should return the PIPE-1 table information as passed pipe=1 as the param.

Our application would call the TDI code to get the info.
But In the definition of TDILeaf.info() function. it will not receive PIPE-ID as parameter.
TDILeaf.info(self, return_info, print_info)

The workaround we found is: If user wants to get the info for pipe1, then he has to go into pipe1 node in cli and run info(pipe=1).

Interoperation with obsdb

Has there been any consideration given to the goal of interoperating with a DB such as OVSDB which is also designed for managing SDNs? OVSDB has its own JSON format.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.