/* ds_tm_wred.asl - buffer management for DiffServ example */ /* * Discrete Weighted RED for tri-color scheme */ #include "tmNp5.h" #define CLR_GREEN 0b00 #define CLR_YELLOW 0b01 #define CLR_RED 0b10 /* Queue size limits for different colors */ unsigned qthresh_red_min param_block_in_extended[ 0:1 ]; unsigned qthresh_red_max param_block_in_extended[ 2:3 ]; unsigned qthresh_yellow_min param_block_inout_extended[ 0:1 ]; unsigned qthresh_yellow_max param_block_inout_extended[ 2:3 ]; unsigned qthresh_green_min param_block_inout_extended[ 4:5 ]; unsigned qthresh_green_max param_block_inout_extended[ 6:7 ]; /* average queue size */ unsigned Qaverage param_block_inout_extended[ 8:9 ]; /* Queue steps (4 steps per interval) */ unsigned qstep_red param_block_inout_extended[ 10:11 ]; unsigned qstep_yellow param_block_inout_extended[ 12:13 ]; unsigned qstep_green param_block_inout_extended[ 14:15 ]; /* color of the PDU (passed by FPL) */ unsigned color parameters_tm[1]; /* drop probability for current PDU */ unsigned(1) drop_pr; /* * weighted running average for the queue size * as if current PDU is not dropped */ unsigned(2) q_average; /* temporaries for min and max queue sizes */ unsigned(2) qthresh_min; unsigned(2) qthresh_max; /* step to increment queue size threshold */ unsigned(2) q_step; script tm_wred { /* * compute average queue size as if the PDU is not dropped * Qaverage = Qaverage + 1/8*(Qcurrent-Qaverage) */ q_average = Qaverage + ((blocks_in_Q + pdu_blocks)>>3) - (Qaverage>>3); /* Set thresholds according to color of current PDU */ if (color == CLR_GREEN) { qthresh_min = qthresh_green_min; qthresh_max = qthresh_green_max; q_step = qstep_green; } else { if (color == CLR_YELLOW) { qthresh_min = qthresh_yellow_min; qthresh_max = qthresh_yellow_max; q_step = qstep_yellow; } else { qthresh_min = qthresh_red_min; qthresh_max = qthresh_red_max; q_step = qstep_red; } } /* * Calculate drop probability, depending on the * threshold interval for the current packet */ if ((q_average > qthresh_max) || (sch_mem > sch_thresh) || (port_mem > port_thresh) || (used_mem > glob_thresh1)) { drop_pr = 0xff; /* (100% drop probability) */ } else { drop_pr = 0x00; /* (0% drop probability) */ if (q_average > qthresh_min) { drop_pr = 0x3f; /* (25% drop probability) */ } if (q_average > (qthresh_min+q_step)) { drop_pr = 0x7f; /* (50% drop probability) */ } if (q_average > (qthresh_max-q_step)) { drop_pr = 0xbf; /* (75% drop probability) */ } } /* Drop decision */ if (random[1] < drop_pr) { /* PDU dropped */ drop=true; } else { /* PDU not dropped, update Qaverage */ Qaverage=q_average; } }