首页 > 其他分享 >MAFIA:1.1 - OpenFlow statistics (Counters, Timestamps)(mafia-sdn/p4demos/demos/1-openflow/1.1-statis

MAFIA:1.1 - OpenFlow statistics (Counters, Timestamps)(mafia-sdn/p4demos/demos/1-openflow/1.1-statis

时间:2022-12-03 18:44:53浏览次数:50  
标签:count statistics 1.1 p4 register ts table my metadata

1.1 - OpenFlow statistics (Counters, Timestamps)
解决的核心问题:如何统计一个流的持续时间

  1. 如何实现一个操作只在数据包第一次出现的时候执行一次,之后再也不执行:设置默认操作,用于更新持续时间。第一次把时间戳从寄存器中读到元数据中,是0,设置一个流表,和元数据中相应字段的匹配key是0,然后执行的action是记录当前时间戳并修改这个字段的元数据为当前时间戳。从此以后这个元数据的相应字段就不在是0了。这个操作也就实现了只在数据包出现的第一次执行的目的。
  2. 如何实现记录一个流的最后一个数据包的时间戳。每个该流的数据包的时间戳来的时候都更新,那最后存的那个时间戳一定是最后一个数据包的时间戳。

mafia-sdn/p4demos/demos/1-openflow/1.1-statistics/commands.txt

table_set_default counter_table _no_op
table_add counter_table do_count 10.0.0.1 10.0.0.2 => 0
table_add counter_table do_count 10.0.0.1 10.0.0.3 => 1
table_add counter_table do_count 10.0.0.2 10.0.0.1 => 2
table_add counter_table do_count 10.0.0.2 10.0.0.3 => 3
table_add counter_table do_count 10.0.0.3 10.0.0.1 => 4
table_add counter_table do_count 10.0.0.3 10.0.0.2 => 5
table_set_default duration_table update_duration	(2. 之后的每一次都执行默认的更新持续时间的操作)
table_add duration_table update_start_ts 0 =>	(1. 只有第一次能匹配上这个流表,然后执行存储初始时间的操作)

mafia-sdn/p4demos/demos/1-openflow/1.1-statistics/p4src/includes/counters.p4

#define TABLE_INDEX_WIDTH 3 // Number of bits to index the duration register
#define N_FLOWS_ENTRIES 8 // Number of entries for flow (2^3)

header_type my_metadata_t {
    fields {
        nhop_ipv4: 32;
        pkt_ts: 48; // Loaded with intrinsic metadata: ingress_global_timestamp
        tmp_ts: 48; // Temporary variable to load start_ts    
        pkt_count: 32;
        byte_count: 32;
        register_index: TABLE_INDEX_WIDTH;
    }
}
metadata my_metadata_t my_metadata;



register my_byte_counter {
    width: 32;
    instance_count: N_FLOWS_ENTRIES;
}

register my_packet_counter {
    width: 32;
    instance_count: N_FLOWS_ENTRIES;
}

register start_ts{
    width: 48;
    instance_count: N_FLOWS_ENTRIES;
}
register last_ts{
    width: 48;
    instance_count: N_FLOWS_ENTRIES;
}
register flow_duration{ // Optional register...Duration can be derived from the two timestamp
    width: 48;
    static: duration_table;
    instance_count: N_FLOWS_ENTRIES;
}

mafia-sdn/p4demos/demos/1-openflow/1.1-statistics/p4src/of.p4

#include "includes/headers.p4"
#include "includes/parser.p4"
#include "includes/counters.p4"

action _no_op() {
    drop();
}
action _drop() {
    drop();
}

// Action and table to count packets and bytes. Also load the start_ts to be matched against next table.
action do_count(entry_index) {
    modify_field(my_metadata.register_index, entry_index); // Save the register index
    modify_field(my_metadata.pkt_ts, intrinsic_metadata.ingress_global_timestamp); // Load packet timestamp in custom metadata

    // Update packet counter (read + add + write)更新包计数器
    register_read(my_metadata.pkt_count, my_packet_counter, my_metadata.register_index);
    add_to_field(my_metadata.pkt_count, 1);
    register_write(my_packet_counter, my_metadata.register_index, my_metadata.pkt_count);

    // Update byte counter (read + add + write)更新字节计数器
    register_read(my_metadata.byte_count, my_byte_counter, my_metadata.register_index);
    add_to_field(my_metadata.byte_count, standard_metadata.packet_length);
    register_write(my_byte_counter, my_metadata.register_index, my_metadata.byte_count);
    
    // Cant do the following if register start_ts is associated to another table (eg: duration_table)...
    // Semantic error: "static counter start_ts assigned to table duration_table cannot be referenced in an action called by table counter_table"把寄存器中的值读入到my_metadata.tmp_ts,第一次读到的是0,所以可以匹配上流表,之后的所有读的值都不是0.所以只执行默认的操。
    register_read(my_metadata.tmp_ts, start_ts, entry_index); // Read the start ts for the flow

}
table counter_table {
    reads {
        ipv4.srcAddr : exact;
        ipv4.dstAddr : exact;
    }
    actions {
        do_count;
        _no_op;
    }
    size : 1024;
}

// Action and table to update the start and end timestamp of the flow.
// Optionally, the duration can as well be stored in a register.

// Action is called only when start_ts=0 (value loaded in my_metadata from my_count action)
action update_start_ts(){
    register_write(start_ts, my_metadata.register_index, my_metadata.pkt_ts); // Update start_ts
    update_duration();
}
// Default action: only update the timestamp for the last matched packet and the duration默认操作,用于得到最后一个数据包的时间戳和当前持续时间。
action update_duration(){
    register_write(last_ts, my_metadata.register_index, my_metadata.pkt_ts); // Update ts of the last seen packet  
    subtract_from_field(my_metadata.pkt_ts, my_metadata.tmp_ts); // Calculate duration
    register_write(flow_duration, my_metadata.register_index, my_metadata.pkt_ts); // Optional: save duration in stateful register
}
table duration_table{
    reads{
        my_metadata.tmp_ts : exact;
    }
    actions{
        update_start_ts;
        update_duration;
    }
}

control ingress { 
  apply(counter_table);
  apply(duration_table);
}


table table_drop {
    actions { 
        _drop;
    }
}
control egress {
    apply(table_drop);
}

标签:count,statistics,1.1,p4,register,ts,table,my,metadata
From: https://www.cnblogs.com/p4p4p4/p/16948557.html

相关文章