p4_testbed/l1switch/CoDel.p4
Tuan-Dat Tran 9c3ef212c2 Added p4-code tested with
Signed-off-by: Tuan-Dat Tran <tuan-dat.tran@tudattr.dev>
2024-12-23 16:49:32 +01:00

166 lines
5.0 KiB
Plaintext

/*
* Copyright 2020-present Ralf Kundel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define SOJOURN_TARGET 5000000 //in nsec
#define CONTROL_INTERVAL 100000000 //in nsec
typedef bit<32> data_t;
typedef bit<1> box_num_t;
struct register_operations {
bit<32> val1;
bit<32> val2;
}
struct codel_metadata_t{
bit<32> egress_tstamp;
bit<32> queue_delay;
bit<32> sojourn_remainder;
bit<1> sojourn_violation;
bit<1> first_sojourn_violation;
bit<1> codel_drop;
bit<32> drop_counter_result;
bit<8> temp_flag;
bit<16> temp_tstamp_high;
bit<32> temp_tstamp_low;
}
control CoDelEgress (in bit<48> ingress_tstamp,
in bit<48> egress_tstamp,
in bit<9> egress_port,
inout headers_t hdr,
inout egress_intrinsic_metadata_for_deparser_t eg_intr_md_for_dprsr){
codel_metadata_t codel_metadata;
//Drop Counter
Register<data_t, box_num_t>(32w1) drop_counter;
RegisterAction<data_t, box_num_t, data_t>(drop_counter)
update_counter = {
void apply(inout data_t counter_data, out data_t counter_result){
counter_result = counter_data;
counter_data = counter_result + 1;
}
};
//Stateful ALU1
Register< bit<32>, bit<9> > (32w512) codel_drop_state;
RegisterAction<bit<32>, bit<9>, bit<1> >(codel_drop_state) codel_drop_state_action = {
void apply(inout bit<32> drop_state, out bit<1> first_soujourn_violation){
if(drop_state== 32w0x0 && codel_metadata.sojourn_violation == 1w0x1){
first_soujourn_violation = 1w0x1;
}else{
first_soujourn_violation = 1w0x0;
}
if(codel_metadata.sojourn_violation == 1w0x1){
drop_state = 32w0x1;
}else {
drop_state = 32w0x0;
}
}
};
//Stateful ALU2
MathUnit< bit<32> > (true, -1, 20,
{0x46, 0x48, 0x4b, 0x4e,
0x52, 0x56, 0x5a, 0x60,
0x66, 0x6f, 0x79, 0x87,
0x0, 0x0, 0x0, 0x0}) sqrtn;
Register< register_operations, bit<9>> (32w512) codel_salu_2;
RegisterAction<register_operations, bit<9>, bit<1> >(codel_salu_2) codel_salu_2_action = {
void apply(inout register_operations inout_vals, out bit<1> out_val){
//val2 == drop count
//val1 == next_drop_time
out_val = 1w0x0;
if(codel_metadata.first_sojourn_violation == 1w0x1){
inout_vals.val1 = codel_metadata.egress_tstamp + CONTROL_INTERVAL;
inout_vals.val2 = 1;
} else
if(codel_metadata.egress_tstamp > inout_vals.val1) {
//we want to drop
inout_vals.val2 = inout_vals.val2 + 1;
inout_vals.val1 = inout_vals.val1 + sqrtn.execute(inout_vals.val2);
out_val = 1w0x1;
}
}
};
action a_compute_remainder(){
codel_metadata.sojourn_remainder = SOJOURN_TARGET |-| codel_metadata.queue_delay;
}
table t_compute_remainder {
actions = {
a_compute_remainder;
}
default_action = a_compute_remainder;
}
action a_drop(){
eg_intr_md_for_dprsr.drop_ctl = 3w0x1;
}
apply{
codel_metadata.temp_flag = 8w0x0;
//codel_metadata.drop_counter_result=update_counter.execute((bit<1>)0);
eg_intr_md_for_dprsr.drop_ctl = 3w0x0; //default value, otherwise the value is undefined in case of "non dropping" and everything can happen
codel_metadata.egress_tstamp = (bit<32>) egress_tstamp;
codel_metadata.queue_delay = (bit<32>)(egress_tstamp - ingress_tstamp);
t_compute_remainder.apply();
if(codel_metadata.sojourn_remainder == 0){
codel_metadata.sojourn_violation = 1w0x1;
}else{
codel_metadata.sojourn_violation = 1w0x0;
}
codel_metadata.first_sojourn_violation = codel_drop_state_action.execute(egress_port);
codel_metadata.codel_drop = codel_salu_2_action.execute(egress_port);
if( (codel_metadata.codel_drop == 1w0x1) && (codel_metadata.sojourn_violation == 1w0x1) ){
a_drop();
codel_metadata.drop_counter_result=update_counter.execute((bit<1>)0);
//codel_metadata.temp_flag = 8w0x1;
//write_drop_flag_state.execute(egress_port);
//codel_metadata.temp_tstamp_high = egress_tstamp[47:32];
//write_drop_tstamp_high.execute(egress_port);
//codel_metadata.temp_tstamp_low = egress_tstamp[31:0];
//write_drop_tstamp_low.execute(egress_port);
// //update_counter.execute((bit<1>)0); // update counter
}
else {
//codel_metadata.temp_flag = read_drop_flag_state.execute(egress_port);
//if (codel_metadata.temp_flag == 1) {
/* hdr.my_tstamp.drop_flag = 1;
hdr.my_tstamp.drop_tstamp_high = read_drop_tstamp_high.execute(egress_port);
hdr.my_tstamp.drop_tstamp_low = read_drop_tstamp_low.execute(egress_port);
}
else {
hdr.my_tstamp.drop_flag =0;
}*/
}
}
}