[硕士研究生研究方向]《Euclid:一种基于P4的全网内实时DDoS攻击检测与防御方法》P4代码

headers.p4

#ifndef HEADERS_P4
#define HEADERS_P4

                            // Byte Offsets
header ethernet_t {
    bit<48> dst_addr;       // 00-05
    bit<48> src_addr;       // 06-11
    bit<16> ether_type;     // 12-13
}

// EtherType 0x6605         
header ddosd_t {
    bit<32> pkt_num;        // 14-17
    bit<32> src_entropy;    // 18-21
    bit<32> src_ewma;       // 22-25
    bit<32> src_ewmmd;      // 26-29
    bit<32> dst_entropy;    // 30-33
    bit<32> dst_ewma;       // 34-37
    bit<32> dst_ewmmd;      // 38-41
    bit<8> alarm;           // 42
    bit<8> dr_state;        // 43
    bit<16> ether_type;     // 44-45    [Copied from Ethernet.]
}

header ipv4_t {
    bit<4> version;
    bit<4> ihl;
    bit<6> dscp;
    bit<2> ecn;
    bit<16> total_len;
    bit<16> identification;
    bit<3> flags;
    bit<13> frag_offset;
    bit<8> ttl;
    bit<8> protocol;
    bit<16> hdr_checksum;
    bit<32> src_addr;
    bit<32> dst_addr;
}

struct headers {
    ethernet_t ethernet;
    ddosd_t ddosd;
    ipv4_t ipv4;
}

struct metadata {
    int<32> ip_count;
    bit<32> entropy_term;
    bit<32> pkt_num;
    bit<32> src_entropy;
    bit<32> src_ewma;
    bit<32> src_ewmmd;
    bit<32> dst_entropy;
    bit<32> dst_ewma;
    bit<32> dst_ewmmd;
    bit<8> alarm;
    bit<8> dr_state; 
}

#endif /* HEADERS_P4 */

parser.p4

#ifndef PARSER_P4
#define PARSER_P4

#include "headers.p4"

#define ETHERTYPE_IPV4 0x0800
#define ETHERTYPE_DDOSD 0x6605

parser ParserImpl(packet_in pkt, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
    state start {
        pkt.extract(hdr.ethernet);
        transition select(hdr.ethernet.ether_type) {
            ETHERTYPE_DDOSD: parse_ddosd;
            ETHERTYPE_IPV4: parse_ipv4;
            default: accept;
        }
    }

    state parse_ddosd {
        pkt.extract(hdr.ddosd);
        transition select(hdr.ddosd.ether_type) {
            ETHERTYPE_IPV4: parse_ipv4;
            default: accept;
        }
    }

    state parse_ipv4 {
        pkt.extract(hdr.ipv4);
        transition accept;
    }
}

#endif /* PARSER_P4 */


ddosm.p4

#include <v1model.p4>
#include <core.p4>

#include "parser.p4"

#define ALARM_SESSION 250
#define CS_WIDTH 1280

// To enable debugging, uncomment the following line. 
// 要启用调试,请取消对下面一行的注释。
#define DR_DEBUG 1

// Defense Readiness State 防御准备就绪状态
#define DR_SAFE 0
#define DR_ACTIVE 1
#define DR_COOLDOWN 2

// Packet Classification 报文分类
#define LEGITIMATE 0
#define MALICIOUS 1 

control verifyChecksum(inout headers hdr, inout metadata meta) {

#ifdef DR_DEBUG

    apply {}

#else

    apply {
        verify_checksum(true, {hdr.ipv4.version, hdr.ipv4.ihl, hdr.ipv4.dscp, hdr.ipv4.ecn, hdr.ipv4.total_len, hdr.ipv4.identification, hdr.ipv4.flags, hdr.ipv4.frag_offset, hdr.ipv4.ttl, hdr.ipv4.protocol, hdr.ipv4.src_addr, hdr.ipv4.dst_addr}, hdr.ipv4.hdr_checksum, HashAlgorithm.csum16);
    }

#endif    

}

control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {

    // Observation Window Parameters 观察窗参数
    register<bit<5>>(1) log2_m;
    register<bit<32>>(1) training_len;

    // Observation Window Control 观察窗的控制
    register<bit<32>>(1) ow_counter;
    register<bit<32>>(1) pkt_counter;

    // Mitigation Threshold 降低阈值
    register<int<32>>(1) mitigation_t;

    /*  
    
        Count sketch declarations.  Count sketch的声明
        
        Our prototype has six count sketches: 我们的原型有6张草图:

        CS_Src_Curr, CS_Src_Last, CS_Src_Safe, 
        CS_Dst_Curr, CS_Dst_Last, CS_Dst_Safe.

        "Src" and "Dst" indicate whether the sketch approximates counts for source or destination IP addresses. 
        “Src”和“Dst”表示草图是否与源IP地址或目标IP地址的计数近似。
        "Curr", "Last", and "Safe" indicate the type of observation window to which the sketch refers.  
        “Curr”、“Last”和“Safe”表示草图引用的观察窗口的类型。

        Since P4 does not provide matrices or records, each sketch row requires two sketches, 
        being one for the counter and one for the observation window ID annotations. 
        由于P4不提供矩阵或记录,因此每个草图行需要两个草图,一个用于计数器,另一个用于观察窗口ID注释。
        
    */ 
    
    // CS_Src_Curr (Source IP) (Current OW) 源IP 当前窗口
    // Counters 计数器
    register<int<32>>(CS_WIDTH) cs_src_curr_1;
    register<int<32>>(CS_WIDTH) cs_src_curr_2;
    register<int<32>>(CS_WIDTH) cs_src_curr_3;
    register<int<32>>(CS_WIDTH) cs_src_curr_4;
    // Annotations 观察窗口ID注释
    register<bit<8>>(CS_WIDTH) cs_src_curr_1_wid;
    register<bit<8>>(CS_WIDTH) cs_src_curr_2_wid;
    register<bit<8>>(CS_WIDTH) cs_src_curr_3_wid;
    register<bit<8>>(CS_WIDTH) cs_src_curr_4_wid;

    // CS_Dst_Curr (Destination IP) (Current OW) 目的IP 当前窗口
    // Counters 计数器
    register<int<32>>(CS_WIDTH) cs_dst_curr_1;
    register<int<32>>(CS_WIDTH) cs_dst_curr_2;
    register<int<32>>(CS_WIDTH) cs_dst_curr_3;
    register<int<32>>(CS_WIDTH) cs_dst_curr_4;
    // Annotations 观察窗口ID注释
    register<bit<8>>(CS_WIDTH) cs_dst_curr_1_wid;
    register<bit<8>>(CS_WIDTH) cs_dst_curr_2_wid;
    register<bit<8>>(CS_WIDTH) cs_dst_curr_3_wid;
    register<bit<8>>(CS_WIDTH) cs_dst_curr_4_wid;

    // CS_Src_Last (Source IP) (Last OW) 源IP 上一个窗口
    register<int<32>>(CS_WIDTH) cs_src_last_1;
    register<int<32>>(CS_WIDTH) cs_src_last_2;
    register<int<32>>(CS_WIDTH) cs_src_last_3;
    register<int<32>>(CS_WIDTH) cs_src_last_4;
 
    // CS_Dst_Last (Destination IP) (Last OW) 目的IP 上一个窗口
    register<int<32>>(CS_WIDTH) cs_dst_last_1;
    register<int<32>>(CS_WIDTH) cs_dst_last_2;
    register<int<32>>(CS_WIDTH) cs_dst_last_3;
    register<int<32>>(CS_WIDTH) cs_dst_last_4;
 
    // CS_Src_Safe (Source IP) (Safe OW) 源IP 安全窗口
    register<int<32>>(CS_WIDTH) cs_src_safe_1;
    register<int<32>>(CS_WIDTH) cs_src_safe_2;
    register<int<32>>(CS_WIDTH) cs_src_safe_3;
    register<int<32>>(CS_WIDTH) cs_src_safe_4;
 
    // CS_Dst_Safe (Destination IP) (Safe OW) 目的IP 安全窗口
    register<int<32>>(CS_WIDTH) cs_dst_safe_1;
    register<int<32>>(CS_WIDTH) cs_dst_safe_2;
    register<int<32>>(CS_WIDTH) cs_dst_safe_3;
    register<int<32>>(CS_WIDTH) cs_dst_safe_4;
 
    // Entropy Norms - Fixed point representation: 28 integer bits, 4 fractional bits.
    // 熵范数 - 定点表示:28个整数位,4个小数位。
    register<bit<32>>(1) src_S;
    register<bit<32>>(1) dst_S;

    // Entropy EWMA and EWMMD - Fixed point representation: 14 integer bits, 18 fractional bits.
    // 熵EWMA和EWMMD - 定点表示:14个整数位,18个小数位。
    register<bit<32>>(1) src_ewma;
    register<bit<32>>(1) src_ewmmd;
    register<bit<32>>(1) dst_ewma;
    register<bit<32>>(1) dst_ewmmd;

    // Smoothing and Sensitivity Coefficients 平滑系数和灵敏度系数
    register<bit<8>>(1) alpha;    // Fixed point representation: 0 integer bits, 8 fractional bits.
    // 定点表示:0整数位,8小数位。
    register<bit<8>>(1) k;        // Fixed point representation: 5 integer bits, 3 fractional bits.
    // 定点表示:5个整数位,3个小数位。

    // Defense Readiness State (see the definitions at the beginning of the code).
    // 防御就绪状态(请参阅代码开头的定义)。
    register<bit<8>>(1) dr_state; 

    action drop() {
        mark_to_drop(standard_metadata);
    }

    action forward(bit<9> egress_port) {
        standard_metadata.egress_spec = egress_port;
    }

    // In the SAFE mitigation state, this table applies to ALL packets.
    // 在安全缓解状态下,此表适用于所有数据包。
    // In the ACTIVE and COOLDOWN states, this table applies only to packets considered LEGITIMATE. 
    // 在激活和冷却状态下,此表仅适用于被视为合法的数据包。
    table ipv4_fib {
        key = {
            hdr.ipv4.dst_addr: lpm;
        }
        actions = {
            forward;
            drop;
        }
        default_action = drop();
    }

    // In the ACTIVE and COOLDOWN mitigation states, this table applies only to packets considered MALICIOUS. 
    // 在激活和冷却缓解状态下,此表仅适用于被视为恶意的数据包。
    table ipv4_dpi_fib {
        key = {
            hdr.ipv4.dst_addr: lpm;
        }
        actions = {
            forward;        // Divert to a different interface. 转到不同的接口。
            drop;           // Discard. 丢弃
        }
        default_action = drop();
    }

    action get_entropy_term(bit<32> entropy_term) {
        meta.entropy_term = entropy_term;
    }

    // The two tables below are supposed to be implemented as a single one,
    // but our target (i.e., the simple_switch) does not support two table lookups within the the same control flow.
    // 下面的两个表应该作为单个表实现,
    // 但是我们的目标(即Simple_Switch)不支持同一控制流内的两个表查找。
    table src_entropy_term {
        key = {
            meta.ip_count: lpm;
        }
        actions = {
            get_entropy_term;
        }
        default_action = get_entropy_term(0);
    }

    table dst_entropy_term {
        key = {
            meta.ip_count: lpm;
        }
        actions = {
            get_entropy_term;
        }
        default_action = get_entropy_term(0);
    }

    action cs_hash(in bit<32> ipv4_addr, out bit<32> h1, out bit<32> h2, out bit<32> h3, out bit<32> h4) {
        hash(h1, HashAlgorithm.csum16, 32w0, {ipv4_addr}, 32w0xffffffff);
        hash(h2, HashAlgorithm.crc32, 32w0, {ipv4_addr}, 32w0xffffffff);
        hash(h3, HashAlgorithm.crc16, 32w0, {ipv4_addr}, 32w0xffffffff);
        hash(h4, HashAlgorithm.random, 32w0, {ipv4_addr}, 32w0xffffffff);
    }

    action cs_ghash(in bit<32> ipv4_addr, out int<32> g1, out int<32> g2, out int<32> g3, out int<32> g4) {
        hash(g1, HashAlgorithm.csum16, 32w0, {ipv4_addr}, 32w0xffffffff);
        hash(g2, HashAlgorithm.crc32, 32w0, {ipv4_addr}, 32w0xffffffff);
        hash(g3, HashAlgorithm.crc16, 32w0, {ipv4_addr}, 32w0xffffffff);
        hash(g4, HashAlgorithm.random, 32w0, {ipv4_addr}, 32w0xffffffff);

        // As ghash outputs 0 or 1, we must map 0 to -1.
        // 因为ghash输出0或1,我们必须将0映射到-1。
        g1 = 2*g1 - 1;
        g2 = 2*g2 - 1;
        g3 = 2*g3 - 1;
        g4 = 2*g4 - 1;
    }

    action median(in int<32> x1, in int<32> x2, in int<32> x3, in int<32> x4, out int<32> y) {
        // This is why we should minimize the sketch depth: the median operator is hardcoded.
        // 这就是我们应该最小化草图深度的原因:中值运算符是硬编码的。
        if      ((x1 <= x2 && x1 <= x3 && x1 <= x4 && x2 >= x3 && x2 >= x4) || 
                 (x2 <= x1 && x2 <= x3 && x2 <= x4 && x1 >= x3 && x1 >= x4))
            y = (x3 + x4) >> 1;
        else if ((x1 <= x2 && x1 <= x3 && x1 <= x4 && x3 >= x2 && x3 >= x4) || 
                 (x3 <= x1 && x3 <= x2 && x3 <= x4 && x1 >= x2 && x1 >= x4))
            y = (x2 + x4) >> 1;
        else if ((x1 <= x2 && x1 <= x3 && x1 <= x4 && x4 >= x2 && x4 >= x3) || 
                 (x4 <= x1 && x4 <= x2 && x4 <= x3 && x1 >= x2 && x1 >= x3))
            y = (x2 + x3) >> 1;
        else if ((x2 <= x1 && x2 <= x3 && x2 <= x4 && x3 >= x1 && x3 >= x4) || 
                 (x3 <= x1 && x3 <= x2 && x3 <= x4 && x2 >= x1 && x2 >= x4))
            y = (x1 + x4) >> 1;
        else if ((x2 <= x1 && x2 <= x3 && x2 <= x4 && x4 >= x1 && x4 >= x3) || 
                 (x4 <= x1 && x4 <= x2 && x4 <= x3 && x2 >= x1 && x2 >= x3))
            y = (x1 + x3) >> 1;
        else
            y = (x1 + x2) >> 1;
    }

    apply {
        if (hdr.ipv4.isValid()) {

            // Obtain the Observation Window number from the register.
            // 从寄存器中获取观察窗口号。
            bit<32> current_wid;
            ow_counter.read(current_wid, 0);

            // Obtain the Defense Readiness state from the register.
            // 从寄存器获取防御准备状态。
            bit<8> dr_state_aux;
            dr_state.read(dr_state_aux, 0);

            // Obtain the Mitigation Threshold from the register
            // 从寄存器获得缓解阈值
            int<32> mitigation_t_aux;
            mitigation_t.read(mitigation_t_aux, 0);

            // Variables for Frequency Variation Analysis.
            // 变频分析的变量。
            int<32> f_src_last;
            int<32> f_src_safe;
            int<32> f_dst_last;
            int<32> f_dst_safe;
            int<32> v_src;
            int<32> v_dst;
            int<32> v;

            // --------------------------------------------------------------------------------------------------------            
            // Beginning of source address frequency and entropy norm estimation.
            // 开始源地址频率和熵规范估计。

            // Obtain column IDs for all rows
            // 获取所有行的列ID
            bit<32> src_hash_1;
            bit<32> src_hash_2;
            bit<32> src_hash_3;
            bit<32> src_hash_4;
            cs_hash(hdr.ipv4.src_addr, src_hash_1, src_hash_2, src_hash_3, src_hash_4);

            // Determine whether to increase or decrease counters
            // 确定是否增加或减少计数器
            int<32> src_ghash_1;
            int<32> src_ghash_2;
            int<32> src_ghash_3;
            int<32> src_ghash_4;
            cs_ghash(hdr.ipv4.src_addr, src_ghash_1, src_ghash_2, src_ghash_3, src_ghash_4);

            // Estimate Frequencies for Source Addresses
            // 估算源地址的频率

            // Variables for counters and annotations.
            // 计数器和注释的变量。
            // For frequency approximation and entropy estimation:
            // 对于频率近似和熵估计:
            int<32> src_curr_1;
            bit<8>  src_curr_1_wid;
            int<32> src_curr_2;
            bit<8>  src_curr_2_wid;
            int<32> src_curr_3;
            bit<8>  src_curr_3_wid;
            int<32> src_curr_4;
            bit<8>  src_curr_4_wid;
            // For frequency variation analysis:
            // 用于频率变化分析:
            int<32> src_last_1;
            int<32> src_last_2;
            int<32> src_last_3;
            int<32> src_last_4;
            int<32> src_safe_1;
            int<32> src_safe_2;
            int<32> src_safe_3;
            int<32> src_safe_4;

            // Read counters and annotations.
            // 读取计数器和注释
            // 读取当前的计数器。
            cs_src_curr_1.read(src_curr_1, src_hash_1);                     // Read current counter.
            // 读取当前的注释。
            cs_src_curr_1_wid.read(src_curr_1_wid, src_hash_1);             // Read current annotation. 
            // 读取当前的计数器。
            cs_src_curr_2.read(src_curr_2, src_hash_2);                     // Read current counter.
            // 读取当前的注释。
            cs_src_curr_2_wid.read(src_curr_2_wid, src_hash_2);             // Read current annotation. 
            // 读取当前的计数器。
            cs_src_curr_3.read(src_curr_3, src_hash_3);                     // Read current counter.
            // 读取当前的注释。
            cs_src_curr_3_wid.read(src_curr_3_wid, src_hash_3);             // Read current annotation. 
            // 读取当前的计数器。
            cs_src_curr_4.read(src_curr_4, src_hash_4);                     // Read current counter.
            // 读取当前的注释。
            cs_src_curr_4_wid.read(src_curr_4_wid, src_hash_4);             // Read current annotation. 
            // 读Wlast计数器。
            cs_src_last_1.read(src_last_1, src_hash_1);                     // Read Wlast counter.
            // 读Wlast计数器。
            cs_src_last_2.read(src_last_2, src_hash_2);                     // Read Wlast counter.
            // 读Wlast计数器。
            cs_src_last_3.read(src_last_3, src_hash_3);                     // Read Wlast counter.
            // 读Wlast计数器。
            cs_src_last_4.read(src_last_4, src_hash_4);                     // Read Wlast counter.
            // 读Wsafe计数器。
            cs_src_safe_1.read(src_safe_1, src_hash_1);                     // Read Wsafe counter.
            // 读Wsafe计数器。
            cs_src_safe_2.read(src_safe_2, src_hash_2);                     // Read Wsafe counter.
            // 读Wsafe计数器。
            cs_src_safe_3.read(src_safe_3, src_hash_3);                     // Read Wsafe counter.
            // 读Wsafe计数器。
            cs_src_safe_4.read(src_safe_4, src_hash_4);                     // Read Wsafe counter.

            // Perform counter resets and copies.
            // 执行计数器重置和拷贝。
            // Within an OW, counter resets and copies must occur exactly once for each address.
            // 在OW中,每个地址的计数器重置和复制必须精确地发生一次。
            // We ensure this by checking the window ID annotation (src_curr_d_wid != current_wid): 
            // 我们通过检查窗口ID注释(src_curr_d_wid != current_wid)来确保这一点:
            // the test will only be true for the first occurrence of the address in the OW.
            // 只有在OW中第一次出现该地址时,该测试才为真。

            // At this point we also perform frequency variation analysis. 
            // 在这一点上,我们还进行了频率变化分析。

            // Row 1 Estimate 第1行估计
            // 窗口已更改。
            if (src_curr_1_wid != current_wid[7:0]) {                       // The window has changed.
            	// 这不是第一个窗口。
                if (current_wid[7:0] > 1) {                                 // This is not the first window.
                	// DR状态是安全的。
                    if (dr_state_aux == DR_SAFE) {                          // The DR state is SAFE. 
                    	// 将Wlast计数器复制到WSafe。
                        src_safe_1 = src_last_1;                            // Copy Wlast counter to Wsafe.
                        // 写回
                        cs_src_safe_1.write(src_hash_1, src_safe_1);        // Write back.
                    } 
                }
                // 将Wcurr计数器复制到Wlast。
                src_last_1 = src_curr_1;                                    // Copy Wcurr counter to Wlast.
                // 写回
                cs_src_last_1.write(src_hash_1, src_last_1);                // Write back.
                // 重置计数器。
                src_curr_1 = 0;                                             // Reset the counter.
                // 更新注释。
                cs_src_curr_1_wid.write(src_hash_1, current_wid[7:0]);      // Update the annotation. 
            }

            // Row 2 Estimate 第2行估计
            // 窗口已更改。
            if (src_curr_2_wid != current_wid[7:0]) {                       // The window has changed.
            	// 这不是第一个窗口。
                if (current_wid[7:0] > 1) {                                 // This is not the first window.
                	// DR状态是安全的。
                    if (dr_state_aux == DR_SAFE) {                          // The DR state is SAFE. 
                    	// 将Wlast计数器复制到WSafe.
                        src_safe_2 = src_last_2;                            // Copy Wlast counter to Wsafe.
                        // 写回
                        cs_src_safe_2.write(src_hash_2, src_safe_2);        // Write back.
                    } 
                }    
                // 将Wcurr计数器复制到Wlast。
                src_last_2 = src_curr_2;                                    // Copy Wcurr counter to Wlast.
                // 写回
                cs_src_last_2.write(src_hash_2, src_last_2);                // Write back.
                // 重置计数器。
                src_curr_2 = 0;                                             // Reset the counter.
                // 更新注释。
                cs_src_curr_2_wid.write(src_hash_2, current_wid[7:0]);      // Update the annotation. 
            }

            // Row 3 Estimate 第3行估计
            // 窗口已更改。
            if (src_curr_3_wid != current_wid[7:0]) {                       // The window has changed.
            	// 这不是第一个窗口。
                if (current_wid[7:0] > 1) {                                 // This is not the first window.
                	// DR状态是安全的。
                    if (dr_state_aux == DR_SAFE) {                          // The DR state is SAFE. 
                    	// 将Wlast计数器复制到WSafe。
                        src_safe_3 = src_last_3;                            // Copy Wlast counter to Wsafe.
                        // 写回
                        cs_src_safe_3.write(src_hash_3, src_safe_3);        // Write back.
                    } 
                }     
                // 将Wcurr计数器复制到Wlast。
                src_last_3 = src_curr_3;                                    // Copy Wcurr counter to Wlast.
                // 写回
                cs_src_last_3.write(src_hash_3, src_last_3);                // Write back.
                // 重置计数器。
                src_curr_3 = 0;                                             // Reset the counter.
                // 更新注释。
                cs_src_curr_3_wid.write(src_hash_3, current_wid[7:0]);      // Update the annotation. 
            }

            // Row 4 Estimate 第4行估计
            // 窗口已更改。
            if (src_curr_4_wid != current_wid[7:0]) {                       // The window has changed.
            	// 这不是第一个窗口。
                if (current_wid[7:0] > 1) {                                 // This is not the first window.
                	// DR状态是安全的。
                    if (dr_state_aux == DR_SAFE) {                          // The DR state is SAFE. 
                    	// 将Wlast计数器复制到WSafe。
                        src_safe_4 = src_last_4;                            // Copy Wlast counter to Wsafe.
                        // 写回
                        cs_src_safe_4.write(src_hash_4, src_safe_4);        // Write back.
                    } 
                }     
                // 将Wcurr计数器复制到Wlast。
                src_last_4 = src_curr_4;                                    // Copy Wcurr counter to Wlast.
                // 写回
                cs_src_last_4.write(src_hash_4, src_last_4);                // Write back.
                // 重置计数器。
                src_curr_4 = 0;                                             // Reset the counter.
                // 更新注释。
                cs_src_curr_4_wid.write(src_hash_4, current_wid[7:0]);      // Update the annotation. 
            }


            // Update the counters. 更新计数器。
            // 更新计数器。
            src_curr_1 = src_curr_1 + src_ghash_1;                          // Update the counter.
            // 更新计数器。
            src_curr_2 = src_curr_2 + src_ghash_2;                          // Update the counter.
            // 更新计数器。
            src_curr_3 = src_curr_3 + src_ghash_3;                          // Update the counter.
            // 更新计数器。
            src_curr_4 = src_curr_4 + src_ghash_4;                          // Update the counter.
            
            // Write the counters back to the sketches.
            // 把计数器写回草图上。
            // 写计数器。
            cs_src_curr_1.write(src_hash_1, src_curr_1);                    // Write the counter.
            // 写计数器。
            cs_src_curr_2.write(src_hash_2, src_curr_2);                    // Write the counter.
            // 写计数器。
            cs_src_curr_3.write(src_hash_3, src_curr_3);                    // Write the counter.
            // 写计数器。
            cs_src_curr_4.write(src_hash_4, src_curr_4);                    // Write the counter.

            // ghash and the counter have the same sign; this computes the absolute value.
            // GHash和计数器具有相同的符号;这将计算绝对值。
            src_curr_1 = src_curr_1 * src_ghash_1;                         
            src_curr_2 = src_curr_2 * src_ghash_2;                          
            src_curr_3 = src_curr_3 * src_ghash_3;                          
            src_curr_4 = src_curr_4 * src_ghash_4;                          

            // At this point, we have updated counters in src_curr_1, src_curr_2, src_curr_3, and src_curr_4.
            // 此时,我们已经更新了src_curr_1、src_curr_2、src_curr_3和src_curr_4中的计数器。

            // Count Sketch Source IP Frequency Estimate: store it in meta.ip_count.
            // 计数草图源IP频率估计:存储在meta.ip_count中。
            median(src_curr_1, src_curr_2, src_curr_3, src_curr_4, meta.ip_count);

            // LPM table lookup. Side effect: meta.entropy_term is updated.
            // LPM表查找。副作用:meta.entropy_term被更新。
            // 这避免了在参数为零时必须执行查找。
            if (meta.ip_count > 0)              // This prevents having to perform a lookup when the argument is zero.
                src_entropy_term.apply();
            else
                meta.entropy_term = 0;
            // At this point, meta.entropy_term has the 'increment'.
            // 在这一点上,meta.entropy_term具有‘增量’。

            // Source Entropy Norm Update 
            // 源熵范数更新
            bit<32> src_S_aux;
            src_S.read(src_S_aux, 0);
            src_S_aux = src_S_aux + meta.entropy_term;
            src_S.write(0, src_S_aux);

            // End of source address frequency and entropy norm estimation.
            // 源地址结束频率和熵范数估计。
            // --------------------------------------------------------------------------------------------------------

            // --------------------------------------------------------------------------------------------------------
            // Beginning of destination address frequency and entropy norm estimation. 
            // 目的地址起始频率和熵范数估计。

            // Obtain column IDs for all rows
            // 获取所有行的列ID
            bit<32> dst_hash_1;
            bit<32> dst_hash_2;
            bit<32> dst_hash_3;
            bit<32> dst_hash_4;
            cs_hash(hdr.ipv4.dst_addr, dst_hash_1, dst_hash_2, dst_hash_3, dst_hash_4);

            // Determine whether to increase or decrease counters
            // 确定是增加还是减少计数器
            int<32> dst_ghash_1;
            int<32> dst_ghash_2;
            int<32> dst_ghash_3;
            int<32> dst_ghash_4;
            cs_ghash(hdr.ipv4.dst_addr, dst_ghash_1, dst_ghash_2, dst_ghash_3, dst_ghash_4);

            // Estimate Frequencies for Destination Addresses
            // 估计目标地址的频率

            // Variables for counters and annotations.
            // 计数器和注释的变量。
            // For frequency approximation and entropy estimation:
            // 对于频率近似和熵估计:
            int<32> dst_curr_1;
            bit<8>  dst_curr_1_wid;
            int<32> dst_curr_2;
            bit<8>  dst_curr_2_wid;
            int<32> dst_curr_3;
            bit<8>  dst_curr_3_wid;
            int<32> dst_curr_4;
            bit<8>  dst_curr_4_wid;
            // For frequency variation analysis:
            // 对于频率变化分析:
            int<32> dst_last_1;
            int<32> dst_last_2;
            int<32> dst_last_3;
            int<32> dst_last_4;
            int<32> dst_safe_1;
            int<32> dst_safe_2;
            int<32> dst_safe_3;
            int<32> dst_safe_4;

            // Read counters and annotations.
            cs_dst_curr_1.read(dst_curr_1, dst_hash_1);                     // Read current counter.
            cs_dst_curr_1_wid.read(dst_curr_1_wid, dst_hash_1);             // Read current annotation. 
            cs_dst_curr_2.read(dst_curr_2, dst_hash_2);                     // Read current counter.
            cs_dst_curr_2_wid.read(dst_curr_2_wid, dst_hash_2);             // Read current annotation. 
            cs_dst_curr_3.read(dst_curr_3, dst_hash_3);                     // Read current counter.
            cs_dst_curr_3_wid.read(dst_curr_3_wid, dst_hash_3);             // Read current annotation. 
            cs_dst_curr_4.read(dst_curr_4, dst_hash_4);                     // Read current counter.
            cs_dst_curr_4_wid.read(dst_curr_4_wid, dst_hash_4);             // Read current annotation. 
            cs_dst_last_1.read(dst_last_1, dst_hash_1);                     // Read Wlast counter.
            cs_dst_last_2.read(dst_last_2, dst_hash_2);                     // Read Wlast counter.
            cs_dst_last_3.read(dst_last_3, dst_hash_3);                     // Read Wlast counter.
            cs_dst_last_4.read(dst_last_4, dst_hash_4);                     // Read Wlast counter.
            cs_dst_safe_1.read(dst_safe_1, dst_hash_1);                     // Read Wsafe counter.
            cs_dst_safe_2.read(dst_safe_2, dst_hash_2);                     // Read Wsafe counter.
            cs_dst_safe_3.read(dst_safe_3, dst_hash_3);                     // Read Wsafe counter.
            cs_dst_safe_4.read(dst_safe_4, dst_hash_4);                     // Read Wsafe counter.

           // Row 1 Estimate
            if (dst_curr_1_wid != current_wid[7:0]) {                       // The window has changed.
                if (current_wid[7:0] > 1) {                                 // This is not the first window.
                    if (dr_state_aux == DR_SAFE) {                          // The DR state is SAFE. 
                        dst_safe_1 = dst_last_1;                            // Copy Wlast counter to Wsafe.
                        cs_dst_safe_1.write(dst_hash_1, dst_safe_1);        // Write back.
                    } 
                }     
                dst_last_1 = dst_curr_1;                                    // Copy Wcurr counter to Wlast.
                cs_dst_last_1.write(dst_hash_1, dst_last_1);                // Write back.
                dst_curr_1 = 0;                                             // Reset the counter.
                cs_dst_curr_1_wid.write(dst_hash_1, current_wid[7:0]);      // Update the annotation. 
            }

            // Row 2 Estimate
            if (dst_curr_2_wid != current_wid[7:0]) {                       // The window has changed.
                if (current_wid[7:0] > 1) {                                 // This is not the first window.
                    if (dr_state_aux == DR_SAFE) {                          // The DR state is SAFE. 
                        dst_safe_2 = dst_last_2;                            // Copy Wlast counter to Wsafe.
                        cs_dst_safe_2.write(dst_hash_2, dst_safe_2);        // Write back.
                    } 
                }     
                dst_last_2 = dst_curr_2;                                    // Copy Wcurr counter to Wlast.
                cs_dst_last_2.write(dst_hash_2, dst_last_2);                // Write back.
                dst_curr_2 = 0;                                             // Reset the counter.
                cs_dst_curr_2_wid.write(dst_hash_2, current_wid[7:0]);      // Update the annotation. 
            }

            // Row 3 Estimate
            if (dst_curr_3_wid != current_wid[7:0]) {                       // The window has changed.
                if (current_wid[7:0] > 1) {                                 // This is not the first window.
                    if (dr_state_aux == DR_SAFE) {                          // The DR state is SAFE. 
                        dst_safe_3 = dst_last_3;                            // Copy Wlast counter to Wsafe.
                        cs_dst_safe_3.write(dst_hash_3, dst_safe_3);        // Write back.
                    } 
                }     
                dst_last_3 = dst_curr_3;                                    // Copy Wcurr counter to Wlast.
                cs_dst_last_3.write(dst_hash_3, dst_last_3);                // Write back.
                dst_curr_3 = 0;                                             // Reset the counter.
                cs_dst_curr_3_wid.write(dst_hash_3, current_wid[7:0]);      // Update the annotation. 
            }

            // Row 4 Estimate
            if (dst_curr_4_wid != current_wid[7:0]) {                       // The window has changed.
                if (current_wid[7:0] > 1) {                                 // This is not the first window.
                    if (dr_state_aux == DR_SAFE) {                          // The DR state is SAFE. 
                        dst_safe_4 = dst_last_4;                            // Copy Wlast counter to Wsafe.
                        cs_dst_safe_4.write(dst_hash_4, dst_safe_4);        // Write back.
                    } 
                }     
                dst_last_4 = dst_curr_4;                                    // Copy Wcurr counter to Wlast.
                cs_dst_last_4.write(dst_hash_4, dst_last_4);                // Write back.
                dst_curr_4 = 0;                                             // Reset the counter.
                cs_dst_curr_4_wid.write(dst_hash_4, current_wid[7:0]);      // Update the annotation. 
            }

            // Update the counters.
            dst_curr_1 = dst_curr_1 + dst_ghash_1;                          // Update the counter.
            dst_curr_2 = dst_curr_2 + dst_ghash_2;                          // Update the counter.
            dst_curr_3 = dst_curr_3 + dst_ghash_3;                          // Update the counter.
            dst_curr_4 = dst_curr_4 + dst_ghash_4;                          // Update the counter.
            
            // Write the counters back to the sketches.
            cs_dst_curr_1.write(dst_hash_1, dst_curr_1);                    // Write the counter.
            cs_dst_curr_2.write(dst_hash_2, dst_curr_2);                    // Write the counter.
            cs_dst_curr_3.write(dst_hash_3, dst_curr_3);                    // Write the counter.
            cs_dst_curr_4.write(dst_hash_4, dst_curr_4);                    // Write the counter.

            // ghash and the counter have the same sign; this computes the absolute value.
            dst_curr_1 = dst_curr_1 * dst_ghash_1;                         
            dst_curr_2 = dst_curr_2 * dst_ghash_2;                          
            dst_curr_3 = dst_curr_3 * dst_ghash_3;                          
            dst_curr_4 = dst_curr_4 * dst_ghash_4;                          

            // At this point, we have updated counters in dst_curr_1, dst_curr_2, dst_curr_3, and dst_curr_4.

            // Count Sketch Destination IP Frequency Estimate
            // 计数草图目标IP频率估计
            median(dst_curr_1, dst_curr_2, dst_curr_3, dst_curr_4, meta.ip_count);

            // LPM table lookup. Side effect: meta.entropy_term is updated.
            if (meta.ip_count > 0)
                dst_entropy_term.apply();
            else
                meta.entropy_term = 0;
            // At this point, meta.entropy_term has the 'increment'.    

            // Destination Entropy Norm Update
            // 目标熵范数更新
            bit<32> dst_S_aux;
            dst_S.read(dst_S_aux, 0);
            dst_S_aux = dst_S_aux + meta.entropy_term;
            dst_S.write(0, dst_S_aux);

            // At this point, we already have source and destination entropy norms (src_S and dst_S). 
            // 在这一点上,我们已经有了源熵范数和目标熵范数(src_S和dst_S)。

            // End  of destination address frequency and entropy norm estimation. 
            // 目的地址结束频率和熵范数估计。
            // --------------------------------------------------------------------------------------------------------

            // --------------------------------------------------------------------------------------------------------
            // Beginning of anomaly detection. 
            // 开始异常检测。
            // Step 1: Check whether the Observation Window has ended.
            // 第一步:查看观察窗口是否结束。
            // Step 2: If the OW has ended, estimate the entropies.
            // 第二步:如果OW已经结束,估计熵。
            // Step 3: If we detect an entropy anomaly, signal this condition. Otherwise, just update the moving averages. 
            // 第三步:如果我们检测到熵异常,发信号通知这种情况。否则,只需更新移动平均即可。

            // Step 1: Check whether the Observation Window has ended. 
            //第一步:查看观察窗口是否结束。
           
            //观测窗口大小
            bit<32> m;                              // Observation Window Size
            bit<5> log2_m_aux;
            log2_m.read(log2_m_aux, 0);
            m = 32w1 << log2_m_aux;                 // m = 2^log2(m)
            // 数据包计数器
            pkt_counter.read(meta.pkt_num, 0);      // Packet Counter
            meta.pkt_num = meta.pkt_num + 1;

			  // 观察窗口尚未结束;只需更新计数器即可。
            if (meta.pkt_num != m) {  // Observation Window has not ended yet; just update the counter.
                pkt_counter.write(0, meta.pkt_num);
            } else {                   // End of Observation Window. Begin OW Summarization.
            	 // 观察窗口结束。开始OW总结。
                current_wid = current_wid + 1;
                // 将新OW的编号保存在其寄存器中。
                ow_counter.write(0, current_wid); // Save the number of the new OW in its register. 

                // Step 2: Estimate the entropies. 
                // 第二步:估算熵。

                // We need to calculate Ĥ = log2(m) - Ŝ/m .
                // 我们需要去计算 Ĥ = log2(m) - Ŝ/m .
                // Since our pipeline doesn't implement division, we can use the identity 1/m = 2^(-log2(m)), for positive m. 
                // 因为我们的管道没有实现除法,所以对于正m,我们可以使用等式1/m=2^(-log2(M))。
                // Given that m is an integer power of two and that we already know log2(m), division becomes a right shift by log2(m) bits. 
                // 假设m是2的整数幂,并且我们已经知道log2(M),除法就变成右移log2(M)位。
                // Therefore,  Ĥ = log2(m) - Ŝ/m  =  log2(m) - Ŝ * 2^(-log2(m)).
                // 因此,Ĥ = log2(m) - Ŝ/m  =  log2(m) - Ŝ * 2^(-log2(m)).
                meta.src_entropy = ((bit<32>)log2_m_aux << 4) - (src_S_aux >> log2_m_aux);
                meta.dst_entropy = ((bit<32>)log2_m_aux << 4) - (dst_S_aux >> log2_m_aux);

                // Read moving averages and deviations. 
                // 阅读移动平均数和偏差值。
                src_ewma.read(meta.src_ewma, 0);
                src_ewmmd.read(meta.src_ewmmd, 0);
                dst_ewma.read(meta.dst_ewma, 0);
                dst_ewmmd.read(meta.dst_ewmmd, 0);

#ifdef DR_DEBUG
                if (current_wid == 0) {                           
					// This never happens. When debugging, we preinitialize the traffic model.
					// 这种事从来没有发生过。在调试时,我们预初始化流量模型。
#else
					// 在第一个窗口...
                if (current_wid == 1) {                           // In the first window... 
#endif 
                    meta.src_ewma = meta.src_entropy << 14;      
					// Initialize averages with the first estimated entropies. Averages have 18 fractional bits. 
					// 用第一次估计的熵初始化平均值。平均值为18个小数位。
                    meta.src_ewmmd = 0;
                    meta.dst_ewma = meta.dst_entropy << 14;
                    meta.dst_ewmmd = 0;

                 } else {                                            // Beginning with the second window... 
                 	// 从第二个窗口开始...
                 	// 默认情况下,没有警报。
                    meta.alarm = 0;                                  // By default, there's no alarm. 

                    // Step 3: If we detect an anomaly, signal this condition. Otherwise, just update the moving averages. 
                    // 第三步:如果我们检测到异常,发出信号通知这种情况。否则,只需更新移动平均线即可。

                    bit<32> training_len_aux;
                    training_len.read(training_len_aux, 0);
                    if (current_wid > training_len_aux) {            // If we've finished training, we check for anomalies.
                    	 // 如果我们完成了训练,我们会检查异常情况
                        bit<8> k_aux;
                        k.read(k_aux, 0);

                        bit<32> src_thresh;
                        // K具有3个小数位。
                        src_thresh = meta.src_ewma + ((bit<32>)k_aux*meta.src_ewmmd >> 3);  // k has 3 fractional bits.

                        bit<32> dst_thresh;
                        dst_thresh = meta.dst_ewma - ((bit<32>)k_aux*meta.dst_ewmmd >> 3);

                        if ((meta.src_entropy << 14) > src_thresh || (meta.dst_entropy << 14) < dst_thresh) { // ANOMALY DETECTED.  检测到异常。
                            meta.alarm = 1;  
                            // 启用缓解
                            dr_state_aux = DR_ACTIVE;               // Enables mitigation.
                            // 写回
                            dr_state.write(0, dr_state_aux);        // Write back.        
                            // 写入报头。
                            meta.dr_state = dr_state_aux;           // Write into the header.

                        }
                            
                    }

						// 未检测到攻击;让我们更新EWMA和EWMMD。
                    if (meta.alarm == 0) {  // No attack detected; let's update EWMA and EWMMD. 
                        bit<8> alpha_aux;
                        alpha.read(alpha_aux, 0);
 
                        // Fixed-point alignments:
                        // 定点比对:
                        //   Alpha: 8 fractional bits; Entropy: 4 fractional bits. EWMA and EWMMD: 18 fractional bits.  
                        //Alpha: 8位小数;熵:4位。EWMA和EWMMD: 18位。
                        //   Alpha*Entropy: 8 +  4 = 12 bits; shift left  6 bits to obtain 18 bits. 
                        // Alpha*熵:8 + 4 = 12位;左移6位得到18位。
                        //   Alpha*EWMx:    8 + 18 = 26 bits; shift right 8 bits to obtain 18 bits. 
                        // Alpha*EWMx: 8 + 18 = 26位;向右移8位得到18位。

                        meta.src_ewma = (((bit<32>)alpha_aux*meta.src_entropy) << 6) + (((0x00000100 - (bit<32>)alpha_aux)*meta.src_ewma) >> 8);
                        meta.dst_ewma = (((bit<32>)alpha_aux*meta.dst_entropy) << 6) + (((0x00000100 - (bit<32>)alpha_aux)*meta.dst_ewma) >> 8);

                        if ((meta.src_entropy << 14) >= meta.src_ewma)
                           meta.src_ewmmd = (((bit<32>)alpha_aux*((meta.src_entropy << 14) - meta.src_ewma)) >> 8) + (((0x00000100 - (bit<32>)alpha_aux)*meta.src_ewmmd) >> 8);
                        else
                           meta.src_ewmmd = (((bit<32>)alpha_aux*(meta.src_ewma - (meta.src_entropy << 14))) >> 8) + (((0x00000100 - (bit<32>)alpha_aux)*meta.src_ewmmd) >> 8);

                        if ((meta.dst_entropy << 14) >= meta.dst_ewma)
                           meta.dst_ewmmd = (((bit<32>)alpha_aux*((meta.dst_entropy << 14) - meta.dst_ewma)) >> 8) + (((0x00000100 - (bit<32>)alpha_aux)*meta.dst_ewmmd) >> 8);
                        else
                            meta.dst_ewmmd = (((bit<32>)alpha_aux*(meta.dst_ewma - (meta.dst_entropy << 14))) >> 8) + (((0x00000100 - (bit<32>)alpha_aux)*meta.dst_ewmmd) >> 8);
                    
                    }

                    // End of Step 3 (Anomaly Detection). 
                    // 步骤3(异常检测)结束。
                    
                } 
                
                // End of Step 2 (Entropy Estimation). 
                // 步骤2(熵估计)结束。

                // Preparation for the next OW: 
                // 为下一个OW做准备:

                // Write back the values for EWMA and EWMMD. 
                // 回写EWMA和EWMMD的值。
                src_ewma.write(0, meta.src_ewma);
                src_ewmmd.write(0, meta.src_ewmmd);
                dst_ewma.write(0, meta.dst_ewma);
                dst_ewmmd.write(0, meta.dst_ewmmd);

                // Reset the packet counter and the entropy terms.
                // 重置包计数器和熵项。
                pkt_counter.write(0, 0);
                src_S.write(0, 0);
                dst_S.write(0, 0);

                // Check whether we should reset Defense Readiness or not. 
                // 检查我们是否应该重置防御准备。
                if (dr_state_aux == DR_ACTIVE && meta.alarm == 0) {
                    dr_state_aux = DR_SAFE;
                    dr_state.write(0, dr_state_aux);  // Write back.
                }

                // Generate a signaling packet. 
                // 生成信令包。
                clone3(CloneType.I2E, ALARM_SESSION, { meta.pkt_num, meta.src_entropy, meta.src_ewma, meta.src_ewmmd, meta.dst_entropy, meta.dst_ewma, meta.dst_ewmmd, meta.alarm, meta.dr_state });

            } // End OW summarization.  结束OW摘要。

            // End of Step 1 (OW Summarization) 步骤1结束(OW摘要)
            // --------------------------------------------------------------------------------------------------------

            // --------------------------------------------------------------------------------------------------------
            // Beginning of Defense-Readiness Processing.
            // 防御开始-准备处理。
            
            bit<1> classification;
            // 默认情况下,将所有数据包归类为合法数据包。
            classification = LEGITIMATE;      // By default, classify all packets as legitimate.       

			  // 缓解处于活动状态
            if (dr_state_aux == DR_ACTIVE) {  // Mitigation is active.        
              
                // Frequency Variation Analysis
                // 频率变异分析

                // Get the estimated counter for the source address at Wlast.
                // 获取Wlast处的源地址的估计计数器。
                src_last_1 = src_last_1 * src_ghash_1;
                src_last_2 = src_last_2 * src_ghash_2;
                src_last_3 = src_last_3 * src_ghash_3;
                src_last_4 = src_last_4 * src_ghash_4;
                median(src_last_1, src_last_2, src_last_3, src_last_4, f_src_last);

                // Get the estimated counter for the source address at Wsafe.
                // 获取WSafe源地址的估计计数器。
                src_safe_1 = src_safe_1 * src_ghash_1;
                src_safe_2 = src_safe_2 * src_ghash_2;
                src_safe_3 = src_safe_3 * src_ghash_3;
                src_safe_4 = src_safe_4 * src_ghash_4;
                median(src_safe_1, src_safe_2, src_safe_3, src_safe_4, f_src_safe);

                // Get the estimated counter for the destination address at Wlast.
                // 获取Wlast的目标地址的估计计数器。
                dst_last_1 = dst_last_1 * dst_ghash_1;
                dst_last_2 = dst_last_2 * dst_ghash_2;
                dst_last_3 = dst_last_3 * dst_ghash_3;
                dst_last_4 = dst_last_4 * dst_ghash_4;
                median(dst_last_1, dst_last_2, dst_last_3, dst_last_4, f_dst_last);

                // Get the estimated counter for the destination address at Wsafe.
                // 在WSafe获取目标地址的估计计数器。
                dst_safe_1 = dst_safe_1 * dst_ghash_1;
                dst_safe_2 = dst_safe_2 * dst_ghash_2;
                dst_safe_3 = dst_safe_3 * dst_ghash_3;
                dst_safe_4 = dst_safe_4 * dst_ghash_4;
                median(dst_safe_1, dst_safe_2, dst_safe_3, dst_safe_4, f_dst_safe);

                // Compute the frequency variations.
                // 计算频率变化。
                v_src = f_src_last - f_src_safe;
                v_dst = f_dst_last - f_dst_safe;
                v = v_dst - v_src;

                // Packet Classification
                // 数据包分类

#ifdef DR_DEBUG

                // Debug mode: write the values into the packet headers
                // 调试模式:将值写入数据包头。
                // Note: the maximum count is 2^18; we divide it by four to make sure it fits in the header field. 
                // 注意:最大计数是2^18;我们将其除以4以确保它适合标题字段。
                hdr.ipv4.identification = (bit<16>) v_src[17:2] ;
                hdr.ipv4.hdr_checksum   = (bit<16>) v_dst[17:2] ;
                
#else

                // Normal operation mode: check whether the frequency variation has exceeded the mitigation threshold.
                // 正常运行模式:检查频率变化是否超过缓解阈值。
                if (v > mitigation_t_aux) {
                    classification = MALICIOUS;
                } 

#endif

            } // End of Defense-Readiness Processing. 
            // 防御结束-准备处理。

            // Policy Enforcement. 
            // 策略执行。


#ifdef DR_DEBUG
            // Debug mode: classify all packets as malicious.
            // 调试模式:将所有数据包归类为恶意数据包。
            classification = MALICIOUS;
#endif

            // Divert is set to one for packets that must undergo further inspection.
            // 对于必须接受进一步检查的数据包,Divert设置为1。
            if (classification == LEGITIMATE) {
            	// 使用常规转发表。
                ipv4_fib.apply();       // Use the regular forwarding table.
            }
            else { 
            	// 使用备用转发表。
                ipv4_dpi_fib.apply();  // Use the alternative forwarding table.
            }

            // End of Policy Enforcement. 策略实施结束。 
            // ----------------------------------------------------------------------------

        } // End of IPv4 header processing. IPv4报头处理结束。
    } // End of ingress pipeline control block.  入口管道控制块末端。
} // End of ingress pipeline definition. 入口管道定义结束。

control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
    const bit<32> CLONE = 1;

    apply {
        if (standard_metadata.instance_type == CLONE) {
            hdr.ddosd.setValid();
            hdr.ddosd.pkt_num = meta.pkt_num;
            hdr.ddosd.src_entropy = meta.src_entropy;
            hdr.ddosd.src_ewma = meta.src_ewma;
            hdr.ddosd.src_ewmmd = meta.src_ewmmd;
            hdr.ddosd.dst_entropy = meta.dst_entropy;
            hdr.ddosd.dst_ewma = meta.dst_ewma;
            hdr.ddosd.dst_ewmmd = meta.dst_ewmmd;
            hdr.ddosd.alarm = meta.alarm;
            hdr.ddosd.dr_state = meta.dr_state;
            hdr.ddosd.ether_type = hdr.ethernet.ether_type;
            hdr.ethernet.ether_type = ETHERTYPE_DDOSD;
        }
    }
}

control computeChecksum(inout headers  hdr, inout metadata meta) {

#ifdef DR_DEBUG

    apply {}

#else

    apply {
        update_checksum(true, {hdr.ipv4.version, hdr.ipv4.ihl, hdr.ipv4.dscp, hdr.ipv4.ecn, hdr.ipv4.total_len, hdr.ipv4.identification, hdr.ipv4.flags, hdr.ipv4.frag_offset, hdr.ipv4.ttl, hdr.ipv4.protocol, hdr.ipv4.src_addr, hdr.ipv4.dst_addr}, hdr.ipv4.hdr_checksum, HashAlgorithm.csum16);
    }

#endif

}

control DeparserImpl(packet_out pkt, in headers hdr) {
    apply {
        pkt.emit(hdr);
    }
}

V1Switch(ParserImpl(), verifyChecksum(), ingress(), egress(), computeChecksum(), DeparserImpl()) main;


  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值