[Home]FPL2 Overview

Wiki Main | RecentChanges | Preferences

No diff available--this is the first major revision. (minor diff)

FPL packet processing language

Introduction

In previous docs we have shown how to use the FFPF framework. Developing such a programmable environment, we introduced FPL (FFPF packet language) and its compiler support. The FPL2 language is summarised in the next picture. It supports all common integer types (signed and unsigned bits, nibbles, octets, words and double words) and allows expressions to get hold of any field in the packet header or payload in a friendly manner. Moreover, offsets in packets can be variable, i.e., determined by an expression. For convenience, an extensible set of macros allows use of shorthand for packet fields, e.g., instead of asking for bytes nine and ten to obtain the IP header's protocol field, a user may abbreviate to `\verb!IP_PROTO!'. As illustrated in the previous figure, most of the operators/expressions are designed in a way that resembles well-known imperative languages such as C or Pascal. We briefly explain constructs that are not intuitively clear.

Restricted FOR loops

For resource safety, the 'FOR' loop construct is limited to loops with a pre-determined number of iterations. Users specify both start and end values of the iteration variable, as well as the amount by which the loop variable should be incremented or decremented after each iteration. The 'BREAK' instruction, allows one to exit the loop `early'. In this case (and also when the loop finishes), execution continues at the instruction following the 'ROF' construct. 'For' loops can be used to test a small range of bytes in the packet or even to scan the entire packet payload for the occurrence of a pattern.

External functions

An essential feature of FFPF is its extensibility and the concept of an `external function' is another key to speed. It is possible for both users and administrators to register FFPF kernel functions (fully optimised native code) that can be called from within the filter expression.

Packet data addressing

The addressing modes of packet data are important for ease of use. Therefore, we support several ways of addressing in order to provide an intuitive way of handling the data. Index addressing mode combined with "variable offset" index addressing mode can give any bit of data within the packet data, as shown in the image below. For improving the readability of programs, we used the lexical conventions according to the industrial standard IEC 61131.

Memory data addressing

Another important addressing mode is used for accessing the memory locations. We support two types of memory: a shared memory array 'MEM' and fast local registers. The shared memory 'MEM' is provided by the FFPF core. Therefore, the filter module does not perform dynamic memory allocation/deallocation. The shared memory is used for data exchange between software modules.

Generally, using data stored in registers increases the processing speed in case of very often used variables. The maximum number of local registers is defined in the `resource restrictions' of the FPL_compiler and depends on the hardware.

As shown below, a memory location is easily accessed (retrieved from / stored in) by using the assignment operator.

M[12]=123+45*6/7-M[8]; // memory access
R[0]=M[8]%R[1];        // register access
R[1]=123+R[1];         // compute the relative index 
M[R[1]] += IP_LEN      // store total packet size
                       // PKT.W[1] (from vocabulary)

Using the language elements already described up to here, an example of filter code is drawn below.

IF ((R[0]<100) && (PKT.W[1]>150))
  // or IP_LEN > 150 (big packets)
THEN
  M[0]+= IP_LEN; // total no. of bytes
  R[0]++;        // count no. of big packets
FI

This trivial example collects the data that is needed to calculate the average size of the first 100 packets larger than 150 bytes. In fact, it counts the total amount of bytes and it keeps track of the number of incoming packets. The purpose of the example is to show how data fields are referenced within packets by using operator \verb!`PKT.'! and also to show how variables are handled, by using memory \verb!`M[]'! and registers \verb!`R[]'!.

Interfacing FFPF with compiled filter object

Assuming that a filter has been compiled in the filter kernel module, it must be inserted and registered by FFPF. The user can simply inject the filter module into the kernel (e.g. `insmod filter_fpl2_nn.o').

Running a test filter application

FFPF comes with a few simple test filter applications called fpl2_xx.kef. The fpl_compiler application compile a .kef file into a kernel module object code (e.g., filter_fpl2_x.ko). User can use the fpl2_builder.sh script that does automatically the compiling of the input .kef script into a kernel object code (e.g., fpl2_builder.sh <filter_name.kef>). Then the kernel module must be loaded by a root user: 'insmod filter_fpl2_x.ko'. The filter start processing all incoming packets and the results can be retrieved by the ffpf user tool through MBuf shared memory.


Wiki Main | RecentChanges | Preferences
This page is read-only | View other revisions
Last edited December 4, 2004 5:32 pm by Wdebruij (diff)
Search: