";
return $form;
}
/*
* For requesting the parameters of the root queue
* to the user like the traffic wizard does.
*/
function build_form() {
$form = "
Name
";
$form .= "
";
$form .= "".$this->GetQname()."";
$form .= "
";
$form .= "
Scheduler Type ";
$form .= "
";
$form .= "
";
$form .= "";
$form .= " ";
$form .= "NOTE: changing this changes all queues underneath!";
$form .= " Beaware you can lose information.";
$form .= "";
$form .= "
";
$form .= "GetTbrConfig();
$form .= "\">";
$form .= " ";
$form .= "Adjusts the size, in bytes, of the token bucket regulator.";
$form .= "If not specified, heuristics based on the interface ";
$form .= "bandwidth are used to determine the size.";
$form .= "
";
$form .= "GetInterface() . "\">";
$form .= "GetQname()."\" >";
return $form;
}
function update_altq_queue_data(&$data) {
$this->ReadConfig($data);
}
/*
* Should call on each of it queues and subqueues
* the same function much like build_rules();
*/
function wconfig() {
$cflink = &get_reference_to_me_in_config($this->GetLink());
if (!is_array($cflink))
$cflink = array();
$cflink['interface'] = $this->GetInterface();
$cflink['name'] = $this->GetQname();
$cflink['scheduler'] = $this->GetScheduler();
$cflink['bandwidth'] = $this->GetBandwidth();
$cflink['bandwidthtype'] = $this->GetBwscale();
$cflink['qlimit'] = $this->GetQlimit();
$cflink['tbrconfig'] = $this->GetTbrConfig();
$cflink['enabled'] = $this->GetEnabled();
}
}
class priq_queue {
var $qname;
var $qinterface;
var $qlimit;
var $qpriority;
var $description;
var $isparent;
var $qbandwidth;
var $qbandwidthtype;
var $qdefault;
var $qrio;
var $qred;
var $qecn;
var $qack;
var $qenabled;
var $qparent;
var $link;
var $available_bw; /* in b/s */
/* This is here to help on form building and building rules/lists */
var $subqueues = array();
/* Accesor functions */
function GetAvailableBandwidth() {
return $this->available_bw;
}
function SetAvailableBandwidth($bw) {
$this->available_bw = $bw;
}
function SetLink($link) {
$this->link = $link;
}
function GetLink() {
return $this->link;
}
function &GetParent() {
return $this->qparent;
}
function SetParent(&$parent) {
$this->qparent = &$parent;
}
function GetEnabled() {
return $this->qenabled;
}
function SetEnabled($value) {
$this->qenabled = $value;
}
function CanHaveChilds() {
return false;
}
function CanBeDeleted() {
return true;
}
function GetQname() {
return $this->qname;
}
function SetQname($name) {
$this->qname = trim($name);
}
function GetBandwidth() {
return $this->qbandwidth;
}
function SetBandwidth($bandwidth) {
$this->qbandwidth = $bandwidth;
}
function GetInterface() {
return $this->qinterface;
}
function SetInterface($name) {
$this->qinterface = trim($name);
}
function GetQlimit() {
return $this->qlimit;
}
function SetQlimit($limit) {
$this->qlimit = $limit;
}
function GetQpriority() {
return $this->qpriority;
}
function SetQpriority($priority) {
$this->qpriority = $priority;
}
function GetDescription() {
return $this->description;
}
function SetDescription($str) {
$this->description = trim($str);
}
function GetFirstime() {
return $this->firsttime;
}
function SetFirsttime($number) {
$this->firsttime = $number;
}
function GetBwscale() {
return $this->qbandwidthtype;
}
function SetBwscale($scale) {
$this->qbandwidthtype = $scale;
}
function GetDefault() {
return $this->qdefault;
}
function SetDefault($value = false) {
$this->qdefault = $value;
altq_set_default_queue($this->GetInterface(), "true");
}
function GetRed() {
return $this->qred;
}
function SetRed($red = false) {
$this->qred = $red;
}
function GetRio() {
return $this->qrio;
}
function SetRio($rio = false) {
$this->qrio = $rio;
}
function GetEcn() {
return $this->qecn;
}
function SetEcn($ecn = false) {
$this->qecn = $ecn;
}
function GetAck() {
return $this->qack;
}
function SetAck($ack = false) {
$this->qack = $ack;
}
function build_javascript() {
$javascript = "";
return $javascript;
}
/*
* Currently this will not be called unless we decide to clonce whole
* queue tree on the 'By Queues' view or support drag&drop on the tree/list
*/
function copy_queue($interface, &$cflink) {
$cflink['name'] = $this->GetQname();
$cflink['interface'] = $interface;
$cflink['qlimit'] = $this->GetQlimit();
$cflink['priority'] = $this->GetQpriority();
$cflink['description'] = $this->GetDescription();
$cflink['enabled'] = $this->GetEnabled();
$cflink['default'] = $this->GetDefault();
$cflink['red'] = $this->GetRed();
$cflink['rio'] = $this->GetRio();
$cflink['ecn'] = $this->GetEcn();
if (is_array($this->subqueues)) {
$cflinkp['queue'] = array();
foreach ($this->subqueues as $q) {
$cflink['queue'][$q->GetQname()] = array();
$q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
}
}
}
function clean_queue($sched) {
clean_child_queues($sched, $this->GetLink());
if (is_array($this->subqueues)) {
foreach ($this->subqueues as $q)
$q->clean_queue($sched);
}
}
function &get_queue_list(&$qlist) {
$qlist[$this->GetQname()] = & $this;
if (is_array($this->subqueues)) {
foreach ($this->subqueues as $queue)
$queue->get_queue_list($qlist);
}
}
function delete_queue() {
unref_on_altq_queue_list($this->GetQname());
if ($this->GetDefault())
altq_set_default_queue($this->GetInterface(), "false");
cleanup_queue_from_rules($this->GetQname());
unset_object_by_reference($this->GetLink());
}
function delete_all() {
if (count($this->subqueues)) {
foreach ($this->subqueues as $q) {
$q->delete_all();
unset_object_by_reference($q->GetLink());
unset($q);
}
unset($this->subqueues);
}
}
function &find_queue($interface, $qname) {
if ($qname == $this->GetQname())
return $this;
}
function find_parentqueue($interface, $qname) { return; }
function validate_input($data, &$input_errors) {
$reqfields[] = "name";
$erqfieldsn[] = "Name";
shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
if ($data['priority'] && (!is_numeric($data['priority'])
|| ($data['priority'] < 1) || ($data['priority'] > 15))) {
$input_errors[] = "The priority must be an integer between 1 and 15.";
}
if ($data['qlimit'] && (!is_numeric($data['qlimit'])))
$input_errors[] = "Queue limit must be an integer";
if ($data['qlimit'] < 0)
$input_errors[] = "Queue limit must be positive";
if (!preg_match("/^[a-zA-Z0-9_-]*$/", $data['name']))
$input_errors[] = "Queue names must be alphanumeric and _ or - only.";
}
function ReadConfig(&$q) {
if (isset($q['name']))
$this->SetQname($q['name']);
if (isset($q['interface']))
$this->SetInterface($q['interface']);
if ($q['bandwidth'] <> "") {
$this->SetBandwidth($q['bandwidth']);
if ($q['bandwidthtype'] <> "")
$this->SetBwscale($q['bandwidthtype']);
}
if (isset($q['qlimit']) && $q['qlimit'] <> "")
$this->SetQlimit($q['qlimit']);
if (isset($q['priority']))
$this->SetQPriority($q['priority']);
if (isset($q['description']) && $q['description'] != "")
$this->SetDescription($q['description']);
if (isset($q['ftpqueue']) && $q['ftpqueue'] <> "")
set_is_ftp_queue($this->GetInterface(), $this->GetQname());
$this->SetRed($q['red']);
$this->SetRio($q['rio']);
$this->SetEcn($q['ecn']);
$this->SetDefault($q['default']);
$this->SetEnabled($q['enabled']);
}
function build_tree() {
$tree = "
";
return $tree;
}
/* Should return something like:
* queue $qname on $qinterface bandwidth ....
*/
function build_rules() {
$pfq_rule = " queue ". $this->qname;
if ($this->GetInterface())
$pfq_rule .= " on ".get_real_wan_interface($this->GetInterface());
if ($this->GetQpriority())
$pfq_rule .= " priority ".$this->GetQpriority();
if ($this->GetQlimit())
$pfq_rule .= " qlimit " . $this->GetQlimit();
if ($this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetDefault()) {
$pfq_rule .= " priq ( ";
if ($this->GetRed()) {
$comma = 1;
$pfq_rule .= " red ";
}
if ($this->GetRio()) {
if ($comma)
$pfq_rule .= " ,";
$comma = 1;
$pfq_rule .= " rio ";
}
if ($this->GetEcn()) {
if ($comma)
$pfq_rule .= " ,";
$comma = 1;
$pfq_rule .= " ecn ";
}
if ($this->GetDefault()) {
if ($comma)
$pfq_rule .= " ,";
$pfq_rule .= " default ";
}
$pfq_rule .= " ) ";
}
$pfq_rule .= " \n";
return $pfq_rule;
}
/*
* To return the html form to show to user
* for getting the parameters.
* Should do even for first time when the
* object is created and later when we may
* need to update it.
*/
function build_form() {
$form .= "
";
$form .= "
";
$form .= "Queue Name
";
$form .= "GetQname());
$form .= "\">";
$form .= " Enter the name of the queue here. Do not use spaces and limit the size to 15 characters.";
$form .= "
";
$form .= "
";
$form .= "
Priority
";
$form .= "
GetQpriority());
$form .= "\">";
$form .= " For hfsc, the range is 0 to 7. The default is 1. Hfsc queues with a higher priority are preferred in the case of overload.
";
$form .= "
";
$form .= "";
$form .= "
Queue limit
";
$form .= "
GetQlimit());
$form .= "\">";
$form .= " Queue limit in packet per second.";
$form .= "
";
$form .= "
";
$form .= "
Scheduler options
";
$form .= "
";
if ($this->GetDefault()) {
$form .= "GetInterface(), $this->GetQname()))
$form .= " CHECKED";
$form .= ">Use this queue for the ftp proxy ";
/* XXX: TODO */
$form .= "GetRed())
$form .= " CHECKED";
$form .= "> Random Early Detection ";
$form .= "GetRio())
$form .= " CHECKED";
$form .= "> Random Early Detection In and Out ";
$form .= "GetEcn())
$form .= " CHECKED";
$form .= "> Explicit Congestion Notification ";
$form .= " Select options for this queue";
$form .= "
The bandwidth share of a backlogged queue - this overrides priority.
";
$form .= "
";
$form .= "The format for service curve specifications is (m1, d, m2). m2 controls";
$form .= "the bandwidth assigned to the queue. m1 and d are optional and can be";
$form .= "used to control the initial bandwidth assignment. For the first d milliseconds the queue gets the bandwidth given as m1, afterwards the value";
$form .= "given in m2.";
$form .= "
";
$form .= "
";
return $form;
}
function update_altq_queue_data(&$data) {
$this->ReadConfig($data);
}
function wconfig() {
$cflink =& get_reference_to_me_in_config($this->GetLink());
if (!is_array($cflink))
$cflink = array();
$cflink['name'] = $this->GetQname();
$cflink['interface'] = $this->GetInterface();
$cflink['qlimit'] = $this->GetQlimit();
$cflink['priority'] = $this->GetQpriority();
$cflink['description'] = $this->GetDescription();
$cflink['bandwidth'] = $this->GetBandwidth();
$cflink['bandwidthtype'] = $this->GetBwscale();
$cflink['enabled'] = $this->GetEnabled();
$cflink['default'] = $this->GetDefault();
$cflink['red'] = $this->GetRed();
$cflink['rio'] = $this->GetRio();
$cflink['ecn'] = $this->GetEcn();
if ($this->GetLinkshare() <> "") {
if ($this->GetL_m1() <> "") {
$cflink['linkshare1'] = $this->GetL_m1();
$cflink['linkshare2'] = $this->GetL_d();
$cflink['linkshare'] = "on";
}
if ($this->GetL_m2() <> "") {
$cflink['linkshare3'] = $this->GetL_m2();
$cflink['linkshare'] = "on";
}
} else $cflink['linkshare'] = "";
if ($this->GetRealtime() <> "") {
if ($this->GetR_m1() <> "") {
$cflink['realtime1'] = $this->GetR_m1();
$cflink['realtime2'] = $this->GetR_d();
$cflink['realtime'] = "on";
}
if ($this->GetR_m2() <> "") {
$cflink['realtime3'] = $this->GetR_m2();
$cflink['realtime'] = "on";
}
} else $cflink['realtime'] = "";
if ($this->GetUpperlimit() <> "") {
if ($this->GetU_m1() <> "") {
$cflink['upperlimit1'] = $this->GetU_m1();
$cflink['upperlimit2'] = $this->GetU_d();
$cflink['upperlimit'] = "on";
}
if ($this->GetU_m2() <> "") {
$cflink['upperlimit3'] = $this->GetU_m2();
$cflink['upperlimit'] = "on";
}
} else $cflink['upperlimit'] = "";
}
}
class cbq_queue extends priq_queue {
var $qborrow;
function GetBorrow() {
return $this->qborrow;
}
function SetBorrow($borrow) {
$this->qborrow = $borrow;
}
function CanHaveChilds() {
return true;
}
function &add_queue($interface, &$qname, &$path, &$input_errors) {
if (!is_array($this->subqueues))
$this->subqueues = array();
$q =& new cbq_queue();
$q->SetInterface($this->GetInterface());
$q->SetParent(&$this);
$q->ReadConfig($qname);
$q->validate_input($qname, $input_errors);
if (count($input_errors)) {
return $q;
}
switch ($q->GetBwscale()) {
case "%":
$myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
break;
default:
$myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
break;
}
$q->SetAvailableBandwidth($myBw);
$this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
$q->SetEnabled("on");
$q->SetLink($path);
$this->subqueues[$q->GetQName()] = &$q;
ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
if (is_array($qname['queue'])) {
foreach ($qname['queue'] as $key1 => $que) {
array_push($path, $key1);
$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
array_pop($path);
}
}
return $q;
}
function copy_queue($interface, &$cflink) {
$cflink['interface'] = $interface;
$cflink['qlimit'] = $this->GetQlimit();
$cflink['priority'] = $this->GetQpriority();
$cflink['name'] = $this->GetQname();
$cflink['description'] = $this->GetDescription();
$cflink['bandwidth'] = $this->GetBandwidth();
$cflink['bandwidthtype'] = $this->GetBwscale();
$cflink['enabled'] = $this->GetEnabled();
$cflink['default'] = $this->GetDefault();
$cflink['red'] = $this->GetRed();
$cflink['rio'] = $this->GetRio();
$cflink['ecn'] = $this->GetEcn();
$cflink['borrow'] = $this->GetBorrow();
if (is_array($this->queues)) {
$cflinkp['queue'] = array();
foreach ($this->subqueues as $q) {
$cflink['queue'][$q->GetQname()] = array();
$q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
}
}
}
/*
* Should search even its childs
*/
function &find_queue($interface, $qname) {
if ($qname == $this->GetQname())
return $this;
foreach ($this->subqueues as $q) {
$result =& $q->find_queue("", $qname);
if ($result)
return $result;
}
}
function &find_parentqueue($interface, $qname) {
if ($this->subqueues[$qname])
return $this;
foreach ($this->subqueues as $q) {
$result = $q->find_parentqueue("", $qname);
if ($result)
return $result;
}
}
function delete_queue() {
unref_on_altq_queue_list($this->GetQname());
if ($this->GetDefault())
altq_set_default_queue($this->GetInterface(), "false");
cleanup_queue_from_rules($this->GetQname());
foreach ($this->subqueues as $q) {
$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
$q->delete_queue();
}
unset_object_by_reference($this->GetLink());
}
function validate_input($data, &$input_errors) {
parent::validate_input($data, $input_errors);
if ($data['priority'] > 7)
$input_errors[] = "Priority must be an integer between 1 and 7.";
$reqfields[] = "bandwidth";
$reqdfieldsn[] = "Bandwidth";
$reqfields[] = "bandwidthtype";
$reqdfieldsn[] = "Bandwidthtype";
shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
if ($data['bandwidth'] && !is_numeric($data['bandwidth']))
$input_errors[] = "Bandwidth must be an integer.";
if ($data['bandwidth'] < 0)
$input_errors[] = "Bandwidth cannot be negative.";
if ($data['bandwidthtype'] == "%") {
if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
$input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
}
/*
$parent =& $this->GetParent();
switch ($data['bandwidthtype']) {
case "%":
$myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
default:
$mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
break;
}
if ($parent->GetAvailableBandwidth() < floatval($myBw))
$input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
*/
}
function ReadConfig(&$q) {
parent::ReadConfig($q);
if ($q['borrow'])
$this->SetBorrow("on");
}
function build_javascript() {
return parent::build_javascript();
}
function build_tree() {
$tree = "
";
return $tree;
}
/* Even this should take childs in consideration */
function build_rules() {
$pfq_rule = "queue ". $this->qname;
if ($this->GetInterface())
$pfq_rule .= " on ".get_real_wan_interface($this->GetInterface());
if ($this->GetBandwidth() && $this->GetBwscale())
$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
if ($this->GetQpriority())
$pfq_rule .= " priority " . $this->GetQpriority();
if ($this->GetQlimit())
$pfq_rule .= " qlimit " . $this->GetQlimit();
if ($this->GetDefault() || $this->GetRed() || $this->GetRio()
|| $this->GetEcn() || $this->GetBuckets() || $this->GetHogs()) {
$pfq_rule .= " fairq ( ";
if ($this->GetRed()) {
$comma = 1;
$pfq_rule .= " red ";
}
if ($this->GetRio()) {
if ($comma)
$pfq_rule .= " ,";
$comma = 1;
$pfq_rule .= " rio ";
}
if ($this->GetEcn()) {
if ($comma)
$pfq_rule .= " ,";
$comma = 1;
$pfq_rule .= " ecn ";
}
if ($this->GetDefault()) {
if ($comma)
$pfq_rule .= " ,";
$comma = 1;
$pfq_rule .= " default ";
}
if ($this->GetBuckets()) {
if ($comma)
$pfq_rule .= ", ";
$pfq_rule .= " buckets " . $this->GetBuckets() . " ";
}
if ($this->GetHogs()) {
if ($comma)
$pfq_rule .= ", ";
$pfq_rule .= " hogs " . $this->GetHogs() . " ";
}
$pfq_rule .= " ) ";
}
$pfq_rule .= " \n";
return $pfq_rule;
}
function build_form() {
$form = "
";
$form .= "
Bandwidth
";
$form .= "
GetBandwidth() > 0)
$form .= htmlspecialchars($this->GetBandwidth());
$form .= "\">";
$form .= " ";
$form .= "Choose the amount of bandwidth for this queue";
$form .= "
";
$form .= parent::build_form();
$form .= "
Scheduler specific options
";
$form .= "
";
$form .= "GetBuckets())
$form .= $this->GetBuckets();
$form .= "\"> Number of buckets available.
";
$form .= "
GetHogs())
$form .= $this->GetHogs();
$form .= "\"> Bandwidth limit for hosts to not saturate link.
";
$form .= "
";
return $form;
}
function update_altq_queue_data(&$data) {
$this->ReadConfig($data);
}
function wconfig() {
$cflink =& get_reference_to_me_in_config($this->GetLink());
if (!is_array($cflink))
$cflink = array();
$cflink['interface'] = $this->GetInterface();
$cflink['qlimit'] = $this->GetQlimit();
$cflink['priority'] = $this->GetQpriority();
$cflink['name'] = $this->GetQname();
$cflink['description'] = $this->GetDescription();
$cflink['bandwidth'] = $this->GetBandwidth();
$cflink['bandwidthtype'] = $this->GetBwscale();
$cflink['enabled'] = $this->GetEnabled();
$cflink['default'] = $this->GetDefault();
$cflink['red'] = $this->GetRed();
$cflink['rio'] = $this->GetRio();
$cflink['ecn'] = $this->GetEcn();
$cflink['buckets'] = $this->GetBuckets();
$cflink['hogs'] = $this->GetHogs();
}
}
/*
* XXX: TODO Link dummynet(4) in the system.
*/
/*
* List of respective objects!
*/
$dummynet_pipe_list = array();
class dummynet_class {
var $qname;
var $qnumber; /* dummynet(4) uses numbers instead of names; maybe integrate with pf the same as altq does?! */
var $qlimit;
var $description;
var $qenabled;
var $link;
var $qparent; /* link to upper class so we do things easily on WF2Q+ rule creation */
var $plr;
var $buckets;
/* mask parameters */
var $mask;
var $noerror;
/* Accesor functions */
function SetLink($link) {
$this->link = $link;
}
function GetLink() {
return $this->link;
}
function Getmask() {
return $this->mask;
}
function SetMask($mask) {
$this->mask = $mask;
}
function &GetParent() {
return $this->qparent;
}
function SetParent(&$parent) {
$this->qparent = &$parent;
}
function GetEnabled() {
return $this->qenabled;
}
function SetEnabled($value) {
$this->qenabled = $value;
}
function CanHaveChilds() {
return false;
}
function CanBeDeleted() {
return true;
}
function GetQname() {
return $this->qname;
}
function SetQname($name) {
$this->qname = trim($name);
}
function GetQlimit() {
return $this->qlimit;
}
function SetQlimit($limit) {
$this->qlimit = $limit;
}
function GetDescription() {
return $this->description;
}
function SetDescription($str) {
$this->descritpion = trim($str);
}
function GetFirstime() {
return $this->firsttime;
}
function SetFirsttime($number) {
$this->firsttime = $number;
}
function GetBuckets() {
return $this->buckets;
}
function SetBuckets($buckets) {
$this->buckets = $buckets;
}
function SetNumber($number) {
$this->qnumber = $number;
}
function GetNumber() {
return $this->qnumber;
}
function GetPlr() {
return $this->plr;
}
function SetPlr($plr) {
$this->plr = $plr;
}
function build_javascript() { return; } /* Do not remove */
function validate_input($data, &$input_errors) {
$reqfields[] = "bandwidth";
$reqdfieldsn[] = "Bandwidth";
$reqfields[] = "bandwidthtype";
$reqdfieldsn[] = "Bandwidthtype";
$reqfields[] = "name";
$reqfieldsn[] = "Name";
shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
if ($data['plr'] && ((!is_numeric($data['plr'])) ||
($data['plr'] <= 0 && $data['plr'] > 1)))
$input_errors[] = "Plr must be an integer between 1 and 100.";
if (($data['buckets'] && (!is_numeric($data['buckets']))) ||
($data['buckets'] < 1 && $data['buckets'] > 100))
$input_errors[] = "Buckets must be an integer between 16 and 65535.";
if ($data['qlimit'] && (!is_numeric($data['qlimit'])))
$input_errors[] = "Queue limit must be an integer";
if (!preg_match("/^[a-zA-Z0-9_-]+$/", $data['name']))
$input_errors[] = "Queue names must be alphanumeric and _ or - only.";
}
}
class dnpipe_class extends dummynet_class {
var $pipe_nr;
var $delay;
var $qbandwidth;
var $qbandwidthtype;
/* This is here to help on form building and building rules/lists */
var $subqueues = array();
function CanHaveChilds() {
return true;
}
function SetDelay($delay) {
$this->delay = $delay;
}
function GetDelay() {
return $this->delay;
}
function GetBwscale() {
return $this->qbandwidthtype;
}
function SetBwscale($scale) {
$this->qbandwidthtype = $scale;
}
function delete_queue() {
cleanup_dnqueue_from_rules($this->GetQname());
foreach ($this->subqueues as $q)
$q->delete_queue();
unset_dn_object_by_reference($this->GetLink());
}
function GetBandwidth() {
return $this->qbandwidth;
}
function SetBandwidth($bandwidth) {
$this->qbandwidth = $bandwidth;
}
function &add_queue($interface, &$queue, &$path, &$input_errors) {
if (!is_array($this->subqueues))
$this->subqueues = array();
$q =& new dnqueue_class();
$q->SetLink($path);
$q->SetEnabled("on");
$q->SetPipe($this->GetQname());
$q->SetParent(&$this);
$q->ReadConfig($queue);
$q->validate_input($queue, $input_errors);
if (count($input_errors))
return $q;
$this->subqueues[$q->GetQname()] = &$q;
return $q;
}
function &get_queue_list($q = null) {
$qlist = array();
$qlist[$this->GetQname()] = $this->GetNumber();
if (is_array($this->subqueues)) {
foreach ($this->subqueues as $queue)
$queue->get_queue_list(&$qlist);
}
return $qlist;
}
/*
* Should search even its childs
*/
function &find_queue($pipe, $qname) {
if ($qname == $this->GetQname())
return $this;
foreach ($this->subqueues as $q) {
$result =& $q->find_queue("", $qname);
if ($result)
return $result;
}
}
function &find_parentqueue($pipe, $qname) {
return NULL;
}
function validate_input($data, &$input_errors) {
parent::validate_input($data, $input_errors);
if ($data['bandwidth'] && (!is_numeric($data['bandwidth'])))
$input_errors[] = "Bandwidth must be an integer.";
if ($data['delay'] && (!is_numeric($data['delay'])))
$input_errors[] = "Delay must be an integer.";
}
function ReadConfig(&$q) {
$this->SetQname($q['name']);
$this->SetNumber($q['number']);
if (isset($q['bandwidth']) && $q['bandwidth'] <> "") {
$this->SetBandwidth($q['bandwidth']);
if (isset($q['bandwidthtype']) && $q['bandwidthtype'])
$this->SetBwscale($q['bandwidthtype']);
}
if (isset($q['qlimit']) && $q['qlimit'] <> "")
$this->SetQlimit($q['qlimit']);
if (isset($q['mask']) && $q['mask'] <> "")
$this->SetMask($q['mask']);
if (isset($q['buckets']) && $q['buckets'] <> "")
$this->SetBuckets($q['buckets']);
if (isset($q['plr']) && $q['plr'] <> "")
$this->SetPlr($q['plr']);
if (isset($q['delay']) && $q['delay'] <> "")
$this->SetDelay($q['delay']);
if (isset($q['description']) && $q['description'] <> "")
$this->SetDescription($q['description']);
$this->SetEnabled($q['enabled']);
}
function build_tree() {
$tree = "
";
$form .= "";
$form .= " ";
$form .= "If 'source' or 'destination' is chosen, \n";
$form .= "a dynamic pipe with the bandwidth, delay, packet loss and queue size given above will \n";
$form .= "be created for each source/destination IP address encountered, \n";
$form .= "respectively. This makes it possible to easily specify bandwidth \n";
$form .= "limits per host.";
$form .= "
";
$form .= "
Description
";
$form .= "
";
$form .= "GetDescription();
$form .= "\">";
$form .= " ";
$form .= "You may enter a description here ";
$form .= "for your reference (not parsed).";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
Delay
";
$form .= "
";
$form .= "GetDelay() . "\">";
$form .= " ms Hint: in most cases, you";
$form .= "should specify 0 here (or leave the field empty)";
$form .= "
";
$form .= "
";
$form .= "
Packet loss rate
";
$form .= "
";
$form .= "GetPlr() . "\">";
$form .= " Hint: in most cases, you";
$form .= "should specify 0 here (or leave the field empty).";
$form .= "A value of 0.001 means one packet in 1000 gets dropped";
$form .= "
";
$form .= "
";
$form .= "
Queue Size
";
$form .= "
";
$form .= "GetQlimit() . "\">";
$form .= " slots ";
$form .= "Hint: in most cases, you ";
$form .= "should leave the field empty. All packets in this pipe are placed into a fixed-size queue first,";
$form .= "then they are delayed by value specified in the Delay field, and then they ";
$form .= "are delivered to their destination.";
$form .= "
";
$form .= "
";
$form .= "
Bucket Size
";
$form .= "
";
$form .= "GetBuckets() . "\">";
$form .= " slots ";
$form .= "Hint: in most cases, you ";
$form .= "should leave the field empty. It increases the hash size set.";
$form .= "
";
return $form;
}
function wconfig() {
$cflink =& get_dn_reference_to_me_in_config($this->GetLink());
if (!is_array($cflink))
$cflink = array();
$cflink['name'] = $this->GetQname();
$cflink['number'] = $this->GetNumber();
$cflink['qlimit'] = $this->GetQlimit();
$cflink['plr'] = $this->GetPlr();
$cflink['description'] = $this->GetDescription();
$cflink['bandwidth'] = $this->GetBandwidth();
$cflink['bandwidthtype'] = $this->GetBwscale();
$cflink['enabled'] = $this->GetEnabled();
$cflink['buckets'] = $this->GetBuckets();
$cflink['mask'] = $this->GetMask();
$cflink['delay'] = $this->GetDelay();
}
}
class dnqueue_class extends dummynet_class {
var $pipeparent;
var $weight;
function GetWeight() {
return $this->weight;
}
function SetWeight($weight) {
$this->weight = $weight;
}
function GetPipe() {
return $this->pipeparent;
}
function SetPipe($pipe) {
$this->pipeparent = $pipe;
}
/* Just a stub in case we ever try to call this from the frontend. */
function &add_queue($interface, &$queue, &$path, &$input_errors) { return; }
function delete_queue() {
cleanup_dnqueue_from_rules($this->GetQname());
unset_dn_object_by_reference($this->GetLink());
}
function validate_input($data, &$input_errors) {
parent::validate_input($data, $input_errors);
if ($data['weight'] && ((!is_numeric($data['weight'])) ||
($data['weight'] < 1 && $data['weight'] > 100)))
$input_errors[] = "Weight must be an integer between 1 and 100.";
}
/*
* Should search even its childs
*/
function &find_queue($pipe, $qname) {
if ($qname == $this->GetQname())
return $this;
else
return NULL;
}
function &find_parentqueue($pipe, $qname) {
return $this->qparent;
}
function &get_queue_list(&$qlist) {
$qlist[$this->GetQname()] = "?" .$this->GetNumber();
}
function ReadConfig(&$q) {
$this->SetQname($q['name']);
$this->SetNumber($q['number']);
if (isset($q['qlimit']) && $q['qlimit'] <> "")
$this->SetQlimit($q['qlimit']);
if (isset($q['mask']) && $q['mask'] <> "")
$this->SetMask($q['mask']);
if (isset($q['weight']) && $q['weight'] <> "")
$this->SetWeight($q['weight']);
if (isset($q['descritption']) && $q['description'] <> "")
$this->SetDescription($q['description']);
$this->SetEnabled($q['enabled']);
}
function build_tree() {
$parent =& $this->GetParent();
$tree = "
";
return $tree;
}
function build_rules() {
if ($this->GetEnabled() == "")
return;
$parent =& $this->GetParent();
$pfq_rule = "dnqueue ". $this->GetNumber() . " dnpipe " . $parent->GetNumber();
if ($this->GetQlimit())
$pfq_rule .= " queue " . $this->GetQimit();
if ($this->GetWeight())
$pfq_rule .= " weight " . $this->GetWeight();
if ($this->GetBuckets())
$pfq_rule .= " buckets " . $this->GetBuckets();
$mask = $this->GetMask();
if (!empty($mask)) {
/* XXX TODO extend this to support more complicated masks */
switch ($mask) {
case 'srcaddress':
$pfq_rule .= " mask src-ip 0xffffffff ";
break;
case 'dstaddress':
$pfq_rule .= " mask dst-ip 0xffffffff ";
break;
default:
break;
}
$pfq_rule .= "\n";
}
return $pfq_rule;
}
function build_form() {
$form = "
Name
";
$form .= "
";
$form .= "GetQname()."\">";
$form .= "
";
$form .= "
Mask
";
$form .= "
";
$form .= "";
$form .= " slots ";
$form .= "If 'source' or 'destination' is chosen, \n";
$form .= "a dynamic pipe with the bandwidth, delay, packet loss and queue size given above will \n";
$form .= "be created for each source/destination IP address encountered, \n";
$form .= "respectively. This makes it possible to easily specify bandwidth \n";
$form .= "limits per host.";
$form .= "
";
$form .= "
Description
";
$form .= "
";
$form .= "GetDescription();
$form .= "\">";
$form .= " ";
$form .= "You may enter a description here ";
$form .= "for your reference (not parsed).";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
";
$form .= "
Weight
";
$form .= "
";
$form .= "GetWeight() . "\">";
$form .= " ms Hint: For queues under the same parent";
$form .= "this specifies the share that a queue gets(values range from 1 to 100, you can leave it blank otherwise)";
$form .= "
";
$form .= "
";
$form .= "
Packet loss rate
";
$form .= "
";
$form .= "GetPlr() . "\">";
$form .= " Hint: in most cases, you";
$form .= "should specify 0 here (or leave the field empty).";
$form .= "A value of 0.001 means one packet in 1000 gets dropped";
$form .= "
";
$form .= "
";
$form .= "
Queue Size
";
$form .= "
";
$form .= "GetQlimit() . "\">";
$form .= " slots ";
$form .= "Hint: in most cases, you ";
$form .= "should leave the field empty. All packets in this pipe are placed into a fixed-size queue first,";
$form .= "then they are delayed by value specified in the Delay field, and then they ";
$form .= "are delivered to their destination.";
$form .= "
";
$form .= "
";
$form .= "
Bucket Size
";
$form .= "
";
$form .= "GetBuckets() . "\">";
$form .= " slots ";
$form .= "Hint: in most cases, you ";
$form .= "should leave the field empty. It increases the hash size set.";
$form .= "
";
$form .= "GetPipe() . "\">";
return $form;
}
function update_dn_data(&$data) {
$this->ReadConfig($data);
}
function wconfig() {
$cflink =& get_dn_reference_to_me_in_config($this->GetLink());
if (!is_array($cflink))
$cflink = array();
$cflink['name'] = $this->GetQname();
$cflink['number'] = $this->GetNumber();
$cflink['qlimit'] = $this->GetQlimit();
$cflink['description'] = $this->GetDescription();
$cflink['weight'] = $this->GetWeight();
$cflink['enabled'] = $this->GetEnabled();
$cflink['buckets'] = $this->GetBuckets();
$cflink['mask'] = $this->GetMask();
}
}
/*
* XXX: TODO Make a class shaper to hide all these function
* from the global namespace.
*/
/*
* This is a layer violation but for now there is no way
* i can find to properly do this with PHP.
*/
function altq_set_default_queue($interface, $value) {
global $altq_list_queues;
$altq_tmp =& $altq_list_queues[$interface];
if ($altq_tmp) {
if ($value) {
$altq_tmp->SetDefaultQueuePresent("true");
}
else {
$altq_tmp->SetDefaultQueuePresent("false");
}
}
}
function altq_get_default_queue($interface) {
global $altq_list_queues;
$altq_tmp = $altq_list_queues[$interface];
if ($altq_tmp)
return $altq_tmp->GetDefaultQueuePresent();
}
function altq_check_default_queues() {
global $altq_list_queues;
$count = 0;
if (is_array($altq_list_queues)) {
foreach($altq_list_queues as $altq) {
if ($altq->GetDefaultQueuePresent())
$count++;
}
}
else $count++;;
return 0;
}
function &get_unique_queue_list() {
global $altq_list_queues;
$qlist = array();
if (is_array($altq_list_queues)) {
foreach ($altq_list_queues as $altq) {
$tmplist =& $altq->get_queue_list();
foreach ($tmplist as $qname => $link)
$qlist[$qname] = $link;
}
}
return $qlist;
}
function &get_unique_dnqueue_list() {
global $dummynet_pipe_list;
$qlist = array();
if (is_array($dummynet_pipe_list)) {
foreach ($dummynet_pipe_list as $dn) {
$tmplist =& $dn->get_queue_list();
foreach ($tmplist as $qname => $link)
$qlist[$qname] = $link;
}
}
return $qlist;
}
function get_is_ftp_queue($interface, $qname) {
global $config;
if (isset($config['interfaces'][$interface]['ftpqueue']) &&
$config['interfaces'][$interface]['ftpqueue'] == $qname)
return true;
return false;
}
function set_is_ftp_queue($interface, $qname) {
global $config;
if (!is_array($config['interfaces'][$interface]['ftpqueue']))
$config['interfaces'][$interface]['ftpqueue'] = array();
$config['interfaces'][$interface]['ftpqueue'] = $qname;
}
function ref_on_altq_queue_list($parent, $qname) {
if (isset($GLOBALS['queue_list'][$qname]))
$GLOBALS['queue_list'][$qname]++;
else
$GLOBALS['queue_list'][$qname] = 1;
unref_on_altq_queue_list($parent);
}
function unref_on_altq_queue_list($qname) {
$GLOBALS['queue_list'][$qname]--;
if ($GLOBALS['queue_list'][$qname] <= 1)
unset($GLOBALS['queue_list'][$qname]);
}
function read_altq_config() {
global $altq_list_queues, $config;
$path = array();
$a_int = &$config['shaper']['queue'];
$altq_list_queues = array();
if (!is_array($config['shaper']['queue']))
return;
foreach ($a_int as $key => $conf) {
$int = $conf['interface'];
$root =& new altq_root_queue();
$root->SetInterface($int);
$altq_list_queues[$root->GetInterface()] = &$root;
$root->ReadConfig($conf);
array_push($path, $key);
$root->SetLink($path);
if (is_array($conf['queue'])) {
foreach ($conf['queue'] as $key1 => $q) {
array_push($path, $key1);
/*
* XXX: we compeletely ignore errors here but anyway we must have
* checked them before so no harm should be come from this.
*/
$root->add_queue($root->GetInterface(), $q, &$path, $input_errors);
array_pop($path);
}
}
array_pop($path);
}
}
function read_dummynet_config() {
global $dummynet_pipe_list, $config;
$path = array();
$dnqueuenumber = 1;
$dnpipenumber = 1;
$a_int = &$config['dnshaper']['queue'];
$dummynet_pipe_list = array();
if (!is_array($config['dnshaper']['queue'])
|| !count($config['dnshaper']['queue']))
return;
foreach ($a_int as $key => $conf) {
if (empty($conf['name']))
continue; /* XXX: grrrrrr at php */
$root =& new dnpipe_class();
$root->ReadConfig($conf);
$root->SetNumber($dnpipenumber);
$dummynet_pipe_list[$root->GetQname()] = &$root;
array_push($path, $key);
$root->SetLink($path);
if (is_array($conf['queue'])) {
foreach ($conf['queue'] as $key1 => $q) {
array_push($path, $key1);
/* XXX: We cheat a little here till a better way is found. */
$q['number'] = $dnqueuenumber;
/*
* XXX: we compeletely ignore errors here but anyway we must have
* checked them before so no harm should be come from this.
*/
$root->add_queue($root->GetQname(), $q, &$path, $input_errors);
array_pop($path);
$dnqueuenumber++;
}
}
array_pop($path);
$dnpipenumber++;
}
}
function get_interface_list_to_show() {
global $altq_list_queues, $config;
$tree = "";
foreach ($config['interfaces'] as $if => $ifdesc) {
if ($altq_list_queues[$if]) {
continue;
} else {
if (!is_altq_capable($ifdesc['if']))
continue;
if (!isset($ifdesc['enable']) && $if != "lan" && $if != "wan")
continue;
$tree .= "
Welcome to the pfSense Traffic Shaper. ";
$default_shaper_msg .= "The tree on the left helps you navigate through the queues ";
$default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
$default_shaper_ms .= "
";
$default_shaper_msg .= "
";
$dn_default_shaper_msg = "
";
$dn_default_shaper_msg .= "
Welcome to the pfSense Traffic Shaper. ";
$dn_default_shaper_msg .= "The tree on the left helps you navigate through the queues ";
$dn_default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
$dn_default_shaper_ms .= "