P4中的寄存器、计量器、计数器学习
计数器
CounterType
enum CounterType {
packets,
bytes,
packets_and_bytes
}
extern counter
#if V1MODEL_VERSION >= 20200408
<I>
#endif
{
/***
* A counter object is created by calling its constructor. This
* creates an array of counter states, with the number of counter
* states specified by the size parameter. The array indices are
* in the range [0, size-1].
*
* You must provide a choice of whether to maintain only a packet
* count (CounterType.packets), only a byte count
* (CounterType.bytes), or both (CounterType.packets_and_bytes).
*
* Counters can be updated from your P4 program, but can only be
* read from the control plane. If you need something that can be
* both read and written from the P4 program, consider using a
* register.
*/
counter(bit<32> size, CounterType type);
// FIXME -- size arg should be `int` but that breaks typechecking
/***
* count() causes the counter state with the specified index to be
* read, modified, and written back, atomically relative to the
* processing of other packets, updating the packet count, byte
* count, or both, depending upon the CounterType of the counter
* instance used when it was constructed.
*
* @param index The index of the counter state in the array to be
* updated, normally a value in the range [0,
* size-1]. If index >= size, no counter state will be
* updated.
*/
#if V1MODEL_VERSION >= 20200408
void count(in I index);
#else
void count(in bit<32> index);
#endif
}
extern direct_counter {
/***
* A direct_counter object is created by calling its constructor.
* You must provide a choice of whether to maintain only a packet
* count (CounterType.packets), only a byte count
* (CounterType.bytes), or both (CounterType.packets_and_bytes).
* After constructing the object, you can associate it with at
* most one table, by adding the following table property to the
* definition of that table:
*
* counters = <object_name>;
*
* Counters can be updated from your P4 program, but can only be
* read from the control plane. If you need something that can be
* both read and written from the P4 program, consider using a
* register.
*/
direct_counter(CounterType type);
/***
* The count() method is actually unnecessary in the v1model
* architecture. This is because after a direct_counter object
* has been associated with a table as described in the
* documentation for the direct_counter constructor, every time
* the table is applied and a table entry is matched, the counter
* state associated with the matching entry is read, modified, and
* written back, atomically relative to the processing of other
* packets, regardless of whether the count() method is called in
* the body of that action.
*/
void count();
}
#define V1MODEL_METER_COLOR_GREEN 0
#define V1MODEL_METER_COLOR_YELLOW 1
#define V1MODEL_METER_COLOR_RED 2
1)可以选择对数据包计数或对字节计数或二者都进行
2)可以在P4中更新计数器,但是在控制平面只能对计数器进行读操作;
如果想在P4程序中同时进行读、写,那么可以考虑通过寄存器实现
计量器
enum MeterType {
packets,
bytes
}
extern meter
#if V1MODEL_VERSION >= 20200408
<I>
#endif
{
/***
* A meter object is created by calling its constructor. This
* creates an array of meter states, with the number of meter
* states specified by the size parameter. The array indices are
* in the range [0, size-1]. For example, if in your system you
* have 128 different "flows" numbered from 0 up to 127, and you
* want to meter each of those flows independently of each other,
* you could do so by creating a meter object with size=128.
*
* You must provide a choice of whether to meter based on the
* number of packets, regardless of their size
* (MeterType.packets), or based upon the number of bytes the
* packets contain (MeterType.bytes).
*/
meter(bit<32> size, MeterType type);
// FIXME -- size arg should be `int` but that breaks typechecking
/***
* execute_meter() causes the meter state with the specified index
* to be read, modified, and written back, atomically relative to
* the processing of other packets, and an integer encoding of one
* of the colors green, yellow, or red to be written to the result
* out parameter.
*
* @param index The index of the meter state in the array to be
* updated, normally a value in the range [0,
* size-1]. If index >= size, no meter state will be
* updated.
* @param result Type T must be bit<W> with W >= 2. When index is
* in range, the value of result will be assigned 0
* for color GREEN, 1 for color YELLOW, and 2 for
* color RED (see RFC 2697 and RFC 2698 for the
* meaning of these colors). When index is out of
* range, the final value of result is not specified,
* and should be ignored by the caller.
*/
#if V1MODEL_VERSION >= 20200408
void execute_meter<T>(in I index, out T result);
#else
void execute_meter<T>(in bit<32> index, out T result);
#endif
}
extern direct_meter<T> {
/***
* A direct_meter object is created by calling its constructor.
* You must provide a choice of whether to meter based on the
* number of packets, regardless of their size
* (MeterType.packets), or based upon the number of bytes the
* packets contain (MeterType.bytes). After constructing the
* object, you can associate it with at most one table, by adding
* the following table property to the definition of that table:
*
* meters = <object_name>;
*/
direct_meter(MeterType type);
/***
* After a direct_meter object has been associated with a table as
* described in the documentation for the direct_meter
* constructor, every time the table is applied and a table entry
* is matched, the meter state associated with the matching entry
* is read, modified, and written back, atomically relative to the
* processing of other packets, regardless of whether the read()
* method is called in the body of that action.
*
* read() may only be called within an action executed as a result
* of matching a table entry, of a table that has a direct_meter
* associated with it. Calling read() causes an integer encoding
* of one of the colors green, yellow, or red to be written to the
* result out parameter.
*
* @param result Type T must be bit<W> with W >= 2. The value of
* result will be assigned 0 for color GREEN, 1 for
* color YELLOW, and 2 for color RED (see RFC 2697
* and RFC 2698 for the meaning of these colors).
*/
void read(out T result);
}
- 比如说我们的系统有128条flow,我们想去计量每一条flow,那么我们就可以创建一个大小为128的计量器
- size需要在int范围内
- 可以选择类型,对数据包、字节进行计数
执行meter
- 这个操作是对特定的下标的计量器进行读、修改、回写等操作
- 根据result out 参数会有一个整数代表着绿色、黄色、红色
参数T 是一个bit参数,W需要大于2,当index在这个范围内,result将会被置为0(green)、1(yellow)、2(red),index超出range,就会被忽略
direct_meter 可以和一个table相关联,每当table被调用并且有一个表条目匹配
只有和direct_meter相关联的table才能调用read(),这个调用将会给result一个值,代表着GREEN、YELLOW、RED
寄存器
#if V1MODEL_VERSION >= 20200408
extern register<T, I>
#else
extern register<T>
#endif
{
/***
* A register object is created by calling its constructor. This
* creates an array of 'size' identical elements, each with type
* T. The array indices are in the range [0, size-1]. For
* example, this constructor call:
*
* register<bit<32>>(512) my_reg;
*
* allocates storage for 512 values, each with type bit<32>.
*/
register(bit<32> size); // FIXME -- arg should be `int` but that breaks typechecking
/***
* read() reads the state of the register array stored at the
* specified index, and returns it as the value written to the
* result parameter.
*
* @param index The index of the register array element to be
* read, normally a value in the range [0, size-1].
* @param result Only types T that are bit<W> are currently
* supported. When index is in range, the value of
* result becomes the value read from the register
* array element. When index >= size, the final
* value of result is not specified, and should be
* ignored by the caller.
*/
@noSideEffects
#if V1MODEL_VERSION >= 20200408
void read(out T result, in I index);
#else
void read(out T result, in bit<32> index);
#endif
/***
* write() writes the state of the register array at the specified
* index, with the value provided by the value parameter.
*
* If you wish to perform a read() followed later by a write() to
* the same register array element, and you wish the
* read-modify-write sequence to be atomic relative to other
* processed packets, then there may be parallel implementations
* of the v1model architecture for which you must execute them in
* a P4_16 block annotated with an @atomic annotation. See the
* P4_16 language specification description of the @atomic
* annotation for more details.
*
* @param index The index of the register array element to be
* written, normally a value in the range [0,
* size-1]. If index >= size, no register state will
* be updated.
* @param value Only types T that are bit<W> are currently
* supported. When index is in range, this
* parameter's value is written into the register
* array element specified by index.
*/
#if V1MODEL_VERSION >= 20200408
void write(in I index, in T value);
#else
void write(in bit<32> index, in T value);
#endif
}