summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/bihash_16_8.h
AgeCommit message (Collapse)AuthorFilesLines
2018-07-20Fine-grained add / delete lockingDave Barach1-2/+0
Add a bucket-level lock bit. Use a spinlock only when actually allocating, freeing, or splitting a bucket. Should improve multi-thread add/del performance. Change-Id: I3e40e2a8371685457f340d6584dea14e3207f2b0 Signed-off-by: Dave Barach <dave@barachs.net>
2018-06-13Disable bihash bucket-level cachingDave Barach1-1/+1
It'll be interesting to see what the perf trend job says about this change. Change-Id: I66307a19a865011ac9660108098874fa1481c895 Signed-off-by: Dave Barach <dave@barachs.net>
2018-05-25Vectorized bihash_{48,40,24,16}_8 key compareDamjan Marion1-0/+6
bihash_48_8 case: Scalar code: 6 clocks SSE4.2 code: 3 clocks AVX2 code: 2.27 clocks AVX512 code: 1.5 clocks Change-Id: I40700175835a1e7321276e47eadbf9771d3c5a68 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-07-19Add a bihash prefetchable bucket-level cacheDave Barach1-0/+3
According to Maciek, the easiest way to leverage the csit "performance trend" job is to actually merge the patch once verified. Manual testing indicates that the patch improves l2 path performance. Other use-cases are TBD. It's possible that we'll need to back out the patch depending on what happens. Change-Id: Ic0a0363de35ef9be953ad7709c57c3936b73fd5a Signed-off-by: Dave Barach <dave@barachs.net>
2017-06-12Remove calls to crc_u32 and add clib_crc32c for armv8+crcChristophe Fontaine1-26/+4
crc_u32 was not defined for non x86_64 with SSE4.2 processors. Calls to "crc_u32" are removed and replaced by either a call to clib_crc32c or a call to clib_xxhash, as the result is not used as a check value but as a hash. Change-Id: I3af4d68e2e5ebd0c9b0a6090f848d043cb0f20a2 Signed-off-by: Christophe Fontaine <christophe.fontaine@enea.com>
2017-03-01VPP-598: tcp stack initial commitDave Barach1-0/+103
Change-Id: I49e5ce0aae6e4ff634024387ceaf7dbc432a0351 Signed-off-by: Dave Barach <dave@barachs.net> Signed-off-by: Florin Coras <fcoras@cisco.com>
='n219' href='#n219'>219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
# VPP API Language    {#api_lang_doc}

The VPP binary API is a message passing API.
The VPP API language is used to define a RPC interface between VPP and its
control plane. The API messages supports shared memory transport and
Unix domain sockets (SOCK_STREAM).

The wire format is essentially that of a network formatted (big-endian) packed C struct.

The VPP API compiler is located in *src/tools/vppapigen* and can currently
compile to JSON or C (used by the VPP binary itself).

## Language definition

### Defining a messages

There are 3 types of message exchanges:

* Request/Reply
The client sends a request message and the server replies with a
single reply message. The convention is that the reply message is
named as method_name + \_reply.

* Dump/Detail
The client sends a "bulk" request message to the server, and the
server replies with a set of detail messages. These messages may be of
different type. A dump/detail call must be enclosed in a control ping
block (Otherwise the client will not know the end of the bulk
transmission). The method name must end with method + "\_dump", the
reply message should be named method + "\_details". The exception here
is for the methods that return multiple message types
(e.g. sw_interface_dump). The Dump/Detail methods are typically used
for acquiring bulk information, like the complete FIB table.

* Events
The client can register for getting asynchronous notifications from
the server. This is useful for getting interface state changes, and so
on. The method name for requesting notifications is conventionally
prefixed with "want_". E.g. "want_interface_events". Which
notification types results from an event registration is defined in
the service definition.

A message from a client must include the 'client_index', an opaque
cookie identifying the sender, and a 'context' field to let the client
match request with reply.

An example of a message definition. The client sends the show_version request,
the server replies with the show_version_reply.

The *client_index* and *context* fields are required in all requests.
The *context* is returned by the server and is used by the client to
match up request and reply messages.

```
define show_version
{
  u32 client_index;
  u32 context;
};
define show_version_reply
{
  u32 context;
  i32 retval;
  string program [32];
  string version [32];
  string build_date [32];
  /* The final field can be a variable length argument */
  string build_directory [];
};

```

The flags are not used by the clients, but have special meaning
for some of the tracing and debugging of the API.
The *autoreply* flag is a shorthand for a reply message with just a
*retval* field.

```
    define : DEFINE ID '{' block_statements_opt '}' ';'
    define : flist DEFINE ID '{' block_statements_opt '}' ';'
    flist : flag
          | flist flag
    flag : MANUAL_PRINT
         | MANUAL_ENDIAN
         | DONT_TRACE
         | AUTOREPLY

    block_statements_opt : block_statements
    block_statements : block_statement
                     | block_statements block_statement
    block_statement : declaration
                    | option
    declaration : type_specifier ID ';'
                | type_specifier ID '[' ID '=' assignee ']' ';'
    declaration : type_specifier ID '[' NUM ']' ';'
                | type_specifier ID '[' ID ']' ';'
    type_specifier : U8
                   | U16
                   | U32
                   | U64
                   | I8
                   | I16
                   | I32
                   | I64
                   | F64
                   | BOOL
                   | STRING
    type_specifier : ID
```


### Options
The *option* word is used to specify meta information.
The only current use is to specify a semantic version of the .api file itself.

Example:
```
option version = "1.0.0";
```

```

    option : OPTION ID '=' assignee ';'
    assignee : NUM
             | TRUE
             | FALSE
             | STRING_LITERAL
```

### Defining new types

New user defined types are defined just like messages.
A typedef has two forms. It can either define an alias for a
different type (or array).

Example:

```
typedef u8 ip4_address[4];
typedef u8 ip6_address[16];
```

Where the above defines two new types *vl_api_ip4_address_t* and
*vl_api_ip6_address_t*. These are aliases for the underlying
u8 array.

In the other form, it is used to specify an abstract data type.

```
enum address_family {
  ADDRESS_IP4 = 0,
  ADDRESS_IP6,
};

union address_union {
  vl_api_ip4_address_t ip4;
  vl_api_ip6_address_t ip6;
};

typedef address {
  vl_api_address_family_t af;
  vl_api_address_union_t un;
};
```

Where the new type *vl_api_address_t*

```
    typedef : TYPEDEF ID '{' block_statements_opt '}' ';'
    typedef : TYPEDEF declaration
```


### Importing Definitions
You can use definitions from other .api files by importing them.
To import another .api's definitions, you add an import statement
to the top of your file:

import "vnet/ip/ip_types.api";

By default you can only use definitions from directly imported .api files.

The API compiler searches for imported files in a set of directories
specified on the API compiler command line using the --includedir flag.
```
import : IMPORT STRING_LITERAL ';'
```

### Comments

The API language uses C style comments.
```
/* */
//
```

### Enumerations
Enums are similar to enums in C.

Every enum definition must contain a constant that maps to zero
as its first element. This is because:

There must be a zero value, so that we can use 0 as a numeric default value.
The zero value needs to be the first element.

As in C, enums can be used as flags or just as numbers.
The on-wire, and in memory representation size of an enum can be specified.
Not all language bindings will support that. The default size is 4 (u32).

Example
```
enum ip_neighbor_flags
{
  IP_API_NEIGHBOR_FLAG_NONE = 0,
  IP_API_NEIGHBOR_FLAG_STATIC = 0x1,
  IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY = 0x2,
};
```

Which generates the vl_api_ip_neighbor_flags_t in the C binding.
In Python that is represented as an IntFlag object
VppEnum.vl_api_ip_neighbor_flags_t.

```
    enum : ENUM ID '{' enum_statements '}' ';'
    enum : ENUM ID ':' enum_size '{' enum_statements '}' ';'
    enum_size : U8
              | U16
              | U32
    enum_statements : enum_statement
                    | enum_statements enum_statement
    enum_statement : ID '=' NUM ','
                   | ID ','
```

### Services
The service statement defines the relationship between messages.
For request/response and dump/details messages it ties the
request with the reply. For events, it specifies which events
that can be received for a given want_* call.

Example:
```
service {
  rpc want_interface_events returns want_interface_events_reply
    events sw_interface_event;
};

```

Which states that the request want_interface_events returns a
want_interface_events_reply and if enabled the client will
receive sw_interface_event messages whenever interface states changes.

```
    service : SERVICE '{' service_statements '}' ';'
    service_statements : service_statement
                    | service_statements service_statement
    service_statement : RPC ID RETURNS NULL ';'
                         | RPC ID RETURNS ID ';'
                         | RPC ID RETURNS STREAM ID ';'
                         | RPC ID RETURNS ID EVENTS event_list ';'
    event_list : events
               | event_list events
    events : ID
           | ID ','
```


## Types
### Scalar Value Types

.api type|size|C type|Python type
---------|----|------|-----------
i8       |   1|i8    |int
u8       |   1|u8    |int
i16      |   2|i16   |int
u16      |   2|u16   |int
i32      |   4|i32   |int
u32      |   4|u32   |int
i64      |   8|i64   |int
u64      |   8|u64   |int
f64      |   8|f64   |float
bool     |   1|bool  |boolean
string   |variable|vl_api_string_t|str

### User Defined Types
#### vnet/ip/ip_types.api

.api type|size|C type|Python type
---------|----|------|-----------
vl_api_address_t|20|vl_api_address_t|`<class 'ipaddress.IPv4Address'> or <class 'ipaddress.IPv6Address'>`
vl_api_ip4_address_t|4|vl_api_ip4_address_t|`<class 'ipaddress.IPv4Address'>`
vl_api_ip6_address_t|16|vl_api_ip6_address_t|`<class 'ipaddress.IPv6Address'>`
vl_api_prefix_t|21|vl_api_prefix_t|`<class 'ipaddress.IPv4Network'> or <class 'ipaddress.IPv6Network'>`
vl_api_ip4_prefix_t|5|vl_api_ip4_prefix_t|`<class 'ipaddress.IPv4Network'>`
vl_api_ip6_prefix_t|17|vl_api_ip6_prefix_t|`<class 'ipaddress.IPv6Network'>`
vl_api_ip4_address_with_prefix_t|5|vl_api_ip4_address_with_prefix_t|`<class 'ipaddress.IPv4Interface'>`
vl_api_ip6_address_with_prefix_t|17|vl_api_ip6_address_with_prefix_t|`<class 'ipaddress.IPv6Interface'>`

#### vnet/ethernet/ethernet_types.api
.api type|size|C type|Python type
---------|----|------|-----------
vl_api_mac_address_t|6|vl_api_mac_address_t|`class 'vpp_papi.MACAddress'>`

#### vnet/interface_types.api
.api type|size|C type|Python type
---------|----|------|-----------
vl_api_interface_index_t|4|vl_api_interface_index_t|int

### New explicit types

#### String versus bytes
A byte string with a maximum length of 64:
```
u8 name[64];
```
Before the "string" type was added, text string were defined like this.
The implications of that was the user would have to know if the field
represented a \0 ended C-string or a fixed length byte string.
The wire format of the 'string' type is a u32 length

An IPv4 or IPv6 address was previously defined like:
```
u8 is_ip6;
u8 address[16];
```

Which made it hard for language bindings to represent the
address as anything but a byte string.
The new explicit address types are shown above.

## Language generators

The VPP API compiler currently has two output modules. One generating JSON
and one generating C header files that are directly used by the VPP
infrastructure and plugins.

The C/C++, Python, Go Lua, and Java language bindings are generated based
on the JSON files.

### Future considerations
- [ ] Generate C/C++ (vapi) client code directly from vppapigen
- [ ] Embed JSON definitions into the API server, so dynamic languages
  can download them directly without going via the filesystem and JSON
  files.