Project

General

Profile

Download (149 KB) Statistics
| Branch: | Tag: | Revision:
1 061f78b1 Bill Marquette
<?php
2
/*
3 ac24dc24 Renato Botelho
 * shaper.inc
4 ba360ed7 Stephen Beaver
 *
5 ac24dc24 Renato Botelho
 * part of pfSense (https://www.pfsense.org)
6 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8 8f2f85c3 Luiz Otavio O Souza
 * Copyright (c) 2014-2022 Rubicon Communications, LLC (Netgate)
9 ac24dc24 Renato Botelho
 * All rights reserved.
10 fd9ebcd5 Stephen Beaver
 *
11 ac24dc24 Renato Botelho
 * originally based on m0n0wall (http://m0n0.ch/wall)
12 c5d81585 Renato Botelho
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
13 ac24dc24 Renato Botelho
 * All rights reserved.
14 fd9ebcd5 Stephen Beaver
 *
15 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
16
 * you may not use this file except in compliance with the License.
17
 * You may obtain a copy of the License at
18 fd9ebcd5 Stephen Beaver
 *
19 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
20 fd9ebcd5 Stephen Beaver
 *
21 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
22
 * distributed under the License is distributed on an "AS IS" BASIS,
23
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
 * See the License for the specific language governing permissions and
25
 * limitations under the License.
26 fd9ebcd5 Stephen Beaver
 */
27 061f78b1 Bill Marquette
28 f5881023 Ermal Lu?i
/* XXX: needs some reducing on include. */
29
/* include all configuration functions. */
30 77b86ada Ermal
require_once("globals.inc");
31 061f78b1 Bill Marquette
require_once("functions.inc");
32 8633930d Ermal
require_once("util.inc");
33
require_once("notices.inc");
34 0e2bed22 PiBa-NL
include_once("interfaces.inc");//required for convert_real_interface_to_friendly_interface_name() in get_queue_stats() to get altq interface name.
35
36 727ed08b Christian McDonald
// Try to ceil $value, otherwise return $default is unable to do so
37
function ceil2($value, $default = NULL)
38
{
39
    return (is_numeric($value) ? ceil($value) : $default);
40
}
41
42 254581a5 Matt Underscore
/* Limiter patch */
43
// I need this crazy looking model/struct to specify various algos, ecn caps, and params.
44
// update as needed when dummynet changes
45
46
// List of schedulers ('type' command on scheduler/pipe) that dummynet/ipfw is supposed to support
47
function getSchedulers() {
48
	return array(
49 25d029d1 Luiz Souza
		"wf2q+" => array(
50
			"name" => "Worst-case Weighted fair Queueing (default)",
51
			"parameter_format" => "type wf2q+",
52
			"description" => "Worst-case Weighted fair Queueing (WF2Q+) schedules flows with an associated weight. ".
53
					 "WF2Q+ is the default algorithm used by previous versions.",
54
			"parameters" => array(),
55
			"ecn" => false
56
		),
57 254581a5 Matt Underscore
		"fifo" => array(
58
			"name" => "FIFO",
59
			"parameter_format" => "type fifo",
60 25d029d1 Luiz Souza
			"description" => "First-in-First-out is a fundamental queueing discipline which ensures packet sequence. ".
61
					 "Dynamic queues are not supported with the FIFO scheduler (all packets are stored in a single queue).",
62 254581a5 Matt Underscore
			"parameters" => array(),
63
			"ecn" => false
64
		),
65
		"qfq" => array(
66
			"name" => "Quick Fair Queueing",
67
			"parameter_format" => "type qfq",
68
			"description" => "QFQ is a fast, low-complexity Approximated Fair Queueing scheduler.",
69
			"parameters" => array(),
70
			"ecn" => false
71
		),
72
		"rr" => array(
73
			"name" => "Round Robin",
74
			"parameter_format" => "type rr",
75
			"description" => "Round Robin (RR) schedules packets in a round-robin fashion.",
76
			"parameters" => array(),
77
			"ecn" => false
78
		),
79
		"prio" => array(
80
			"name" => "PRIO",
81
			"parameter_format" => "type prio",
82
			"description" => "PRIO schedules packets by their corresponding priority.",
83
			"parameters" => array(),
84
			"ecn" => false
85
		),
86
		"fq_codel" => array(
87
			"name" => "FQ_CODEL",
88 1de72f61 Matt Underscore
			"parameter_format" => "type fq_codel target %sms interval %sms quantum %s limit %s flows %s",
89 254581a5 Matt Underscore
			"description" => "CoDel is a novel \"no knobs\", \"just works\", \"handles variable bandwidth and RTT\", and simple AQM algorithm."
90
							. " As a scheduler, FQ_CODEL implements several flows (defined below), each having their own CoDel AQM.",
91
			"parameters" => array(
92 d4f29a52 Steve Beaver
				"target" => array("name" => "Target Delay (ms)", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqcodel.target")) / 1000),
93
				"interval" => array("name" => "Interval (ms)", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqcodel.interval")) / 1000),
94 254581a5 Matt Underscore
				"quantum" => array("name" => "quantum", "type" => "number", "default" => get_single_sysctl("net.inet.ip.dummynet.fqcodel.quantum")),
95
				"limit" => array("name" => "limit", "type" => "number", "default" => get_single_sysctl("net.inet.ip.dummynet.fqcodel.limit")),
96
				"flows" => array("name" => "flows", "type" => "number", "default" => get_single_sysctl("net.inet.ip.dummynet.fqcodel.flows"))
97
			),
98
			"ecn" => true
99
		),
100
		"fq_pie" => array(
101
			"name" => "FQ_PIE",
102 10006140 Harley Peters
			"parameter_format" => "type fq_pie target %sms tupdate %sms alpha %s beta %s max_burst %s max_ecnth %s quantum %s limit %s flows %s",
103 254581a5 Matt Underscore
			"description" => "Fair Queue Proportional Integral controller Enhanced AQM (FQ_PIE) is similar to FQ_CODEL but uses a slightly different algorithm.",
104
			"parameters" => array(
105 d4f29a52 Steve Beaver
				"target" => array("name" => "Target Delay (ms)", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.target")) / 1000),
106
				"tupdate" => array("name" => "Interval (ms)", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.tupdate")) / 1000),
107 10006140 Harley Peters
				"alpha" => array("name" => "alpha", "type" => "number step=any", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.alpha")) / 1000),
108
				"beta" => array("name" => "beta", "type" => "number step=any", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.beta")) / 1000),
109
				"max_burst" => array("name" => "max_burst", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.max_burst")) / 1000),
110
				"max_ecnth" => array("name" => "max_ecnth", "type" => "number step=any", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.max_ecnth")) / 1000),
111
				"quantum" => array("name" => "quantum", "type" => "number", "default" => get_single_sysctl("net.inet.ip.dummynet.fqpie.quantum")),
112
				"limit" => array("name" => "limit", "type" => "number", "default" => get_single_sysctl("net.inet.ip.dummynet.fqpie.limit")),
113
				"flows" => array("name" => "flows", "type" => "number", "default" => get_single_sysctl("net.inet.ip.dummynet.fqpie.flows"))
114 254581a5 Matt Underscore
			),
115 10006140 Harley Peters
			"ecn" => true,
116
			"pie_onoff" => true,
117
			"pie_capdrop" => true,
118
			"pie_qdelay" => true,
119
			"pie_pderand" => true
120 254581a5 Matt Underscore
		)
121
	);
122
}
123
// list of AQMs that dummynet supports
124
function getAQMs() {
125
	return array(
126
		"droptail" => array(
127
			"name" => "Tail Drop",
128
			"description" => "Tail Drop is a fundamental queue management algorithm which drops inbound packets once the queue is full.",
129
			"parameter_format" => "droptail",
130
			"parameters" => array(),
131
			"ecn" => false
132
		),
133
		"codel" => array(
134
			"name" => "CoDel",
135
			"description" => "CoDel is a novel \"no knobs\", \"just works\", \"handles variable bandwidth and RTT\", and simple AQM algorithm.",
136
			"parameter_format" => "codel target %sms interval %sms",
137
			"parameters" => array(
138 d4f29a52 Steve Beaver
				"target" => array("name" => "Target Delay (ms)", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.codel.target")) / 1000),
139
				"interval" => array("name" => "Interval (ms)", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.codel.interval")) / 1000),
140 254581a5 Matt Underscore
			),
141
			"ecn" => true
142
		),
143
		"pie" => array(
144
			"name" => "PIE",
145
			"description" => "Proportional Integral controller Enhanced AQM (PIE) is similar to CoDel but uses a slightly different algorithm.",
146
			"parameter_format" => "pie target %sms tupdate %sms alpha %s beta %s max_burst %s max_ecnth %s",
147
			"parameters" => array(
148 d4f29a52 Steve Beaver
				"target" => array("name" => "Target Delay (ms)", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.target")) / 1000),
149
				"tupdate" => array("name" => "Interval (ms)", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.tupdate")) / 1000),
150 10006140 Harley Peters
				"alpha" => array("name" => "alpha", "type" => "number step=any", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.alpha")) / 1000),
151
				"beta" => array("name" => "beta", "type" => "number step=any", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.beta")) / 1000),
152
				"max_burst" => array("name" => "max_burst", "type" => "number", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.max_burst")) / 1000),
153
				"max_ecnth" => array("name" => "max_ecnth", "type" => "number step=any", "default" => intval(get_single_sysctl("net.inet.ip.dummynet.fqpie.max_ecnth")) / 1000)
154 254581a5 Matt Underscore
			),
155 10006140 Harley Peters
			"ecn" => true,
156
			"pie_onoff" => true,
157
			"pie_capdrop" => true,
158
			"pie_qdelay" => true,
159
			"pie_pderand" => true
160 254581a5 Matt Underscore
		),
161
		"red" => array(
162
			"name" => "Random Early Detection (RED)",
163
			"description" => "Random Early Detection (RED) drops packets based on probability, which increases as the queue increases in size.",
164
			"parameter_format" => "red %s/%s/%s/%s",
165
			"parameters" => array(
166
				"w_q" => array("name" => "w_q", "type" => "number", "default" => 1),
167
				"min_th" => array("name" => "min_th", "type" => "number", "default" => 0),
168
				"max_th" => array("name" => "max_th", "type" => "number", "default" => 1),
169
				"max_p" => array("name" => "max_p", "type" => "number", "default" => 1)
170
			),
171
			"ecn" => true
172
		),
173
		"gred" => array(
174
			"name" => "Gentle Random Early Detection (GRED)",
175
			"description" => "Gentle Random Early Detection (GRED) drops packets based on probability, which increases as the queue increases in size.",
176
			"parameter_format" => "gred %s/%s/%s/%s",
177
			"parameters" => array(
178
				"w_q" => array("name" => "w_q", "type" => "number", "default" => 1),
179
				"min_th" => array("name" => "min_th", "type" => "number", "default" => 0),
180
				"max_th" => array("name" => "max_th", "type" => "number", "default" => 1),
181
				"max_p" => array("name" => "max_p", "type" => "number", "default" => 1)
182
			),
183
			"ecn" => true
184
		)
185
	);
186
}
187
// used to map above
188
function array_map_assoc(callable $f, array $a) {
189
	return array_column(array_map($f, array_keys($a), $a), 1, 0);
190
}
191
function build_queue_params($array, $selected, $params, $id) {
192 74b3e6ec Matt Underscore
	$form .= '<div id="params_' . $id . '">';
193 d4f29a52 Steve Beaver
194 254581a5 Matt Underscore
	$selectedAlgorithm = $array[$selected];
195 d4f29a52 Steve Beaver
196 254581a5 Matt Underscore
	if ($selectedAlgorithm) {
197
		$form .= '<span class="help-block">' . gettext($selectedAlgorithm['description']) . '</span><br/>';
198
	}
199 d4f29a52 Steve Beaver
200 254581a5 Matt Underscore
	$parameters = $selectedAlgorithm["parameters"];
201 d4f29a52 Steve Beaver
202 254581a5 Matt Underscore
	if (!$parameters || sizeof($parameters) <= 0) {
203
		if (!$selectedAlgorithm) {
204
			$form .= 'No parameters for selected algorithm.';
205
		} else {
206
			$form .= 'No parameters for ' . $selectedAlgorithm["name"] . '.';
207
		}
208
	} else {
209
		$form .= '<div class="table-responsive">';
210
		$form .= '<table id="maintable" class="table table-hover table-striped">';
211
		$form .= "<thead><tr>";
212
		$form .= "<th>Parameter</th>";
213
		$form .= "<th>Value</th>";
214
		$form .= "</tr></thead>";
215
		$form .= "<tbody>";
216 d4f29a52 Steve Beaver
217 254581a5 Matt Underscore
		foreach ($parameters as $key => $value) {
218
			$form .= '<tr>';
219 d4f29a52 Steve Beaver
220 254581a5 Matt Underscore
			// get current value, or default.
221
			$currentValue = $params[$key];
222 10006140 Harley Peters
			// check if param key is set. using isset allows the param key to be zero.
223
			if (! isset($currentValue)) {
224 254581a5 Matt Underscore
				$currentValue = $value["default"]; // default to default
225
			}
226 d4f29a52 Steve Beaver
227 5ee16aa6 no
			$form .= "<td class=\"col-xs-4\">" . htmlspecialchars($key) . "</td>";
228 d4f29a52 Steve Beaver
			$form .= "<td class=\"col-xs-8\"><input class=\"form-control\" type=" . gettext($value["type"])
229 5ee16aa6 no
					. " name=\"param_" . $selected . "_" . $key . "\" placeholder=\"" .
230
					htmlspecialchars($value["default"]) . "\" value=\"" . htmlspecialchars($currentValue) . "\"/></td>";
231 d4f29a52 Steve Beaver
232 254581a5 Matt Underscore
			$form .= '</tr>';
233
		}
234 d4f29a52 Steve Beaver
235 254581a5 Matt Underscore
		$form .= "</tbody></table></div><br />";
236
	}
237 d4f29a52 Steve Beaver
238 254581a5 Matt Underscore
	$form .= '</div>';
239
	$form .= '<script type="text/javascript">';
240 74b3e6ec Matt Underscore
	$form .= 'events.push(function() {$("#' . $id . '").change(function() {$("#params_' .
241 254581a5 Matt Underscore
		gettext($id) . '").html("Save this limiter to see algorithm parameters.");})});</script>';
242
243
	return($form);
244
}
245
function FormatParameters($format_string, $params) {
246
	return vsprintf($format_string, $params);
247
}
248
/* End limiter patch */
249
250 0e2bed22 PiBa-NL
function get_queue_stats() {
251 0f5bd6f8 Stephen Jones
	// due to sysutils\qstats not providing accurate stats with 'currently' valid numbers
252 0e2bed22 PiBa-NL
	// in its current implementation this php function does the job for now..
253
	$result = array();
254
	$result['timestamp'] = gettimeofday(true);
255
	$r = exec("/sbin/pfctl -s queue -v", $output, $ret);
256
	$interfacestats = array();
257
	foreach($output as $line) {
258
		$partial = explode('{', $line);
259
		$items = explode(" ", $partial[0]);
260
		if (isset($partial[1])) {
261
			$contains = explode(", ", substr($partial[1], 0, strlen($partial[1]) - 1));
262
		} else {
263
			unset($contains);
264
		}
265
		if ($items[0] == "queue") {
266
			$level = 1;
267
			while (empty($items[$level])) {
268
				$level++;
269
			}
270
			unset($newqueue);
271
			$newqueue = array();
272
			$currentqueuename = $items[$level];
273
			$currentqueueif = $items[$level+2];
274
			$newqueue['name'] = $currentqueuename;
275
			$newqueue['interface'] = $items[$level+2];
276 0f5bd6f8 Stephen Jones
277 0e2bed22 PiBa-NL
			if ($items[$level+3] == "bandwidth") {
278
				$level += 2;
279
			}
280
			if ($items[$level+3] == "priority") {
281
				$level += 2;
282
			}
283
			if ($items[$level+3] == "qlimit") {
284
				$level += 2;
285
			}
286
			$tmp = $items[$level+3];
287
			if (substr($tmp,strlen($tmp)-1) == "(") {
288
				$newqueue['shapertype'] = substr($tmp, 0, strlen($tmp)-1);
289
			}
290 0f5bd6f8 Stephen Jones
291 0e2bed22 PiBa-NL
			$interfacestats[$currentqueueif][$currentqueuename] = &$newqueue;
292
			if (is_array($contains)) {
293
				$newqueue['contains'] = $contains;
294
			}
295
		} elseif ($items[0] == "altq") {
296
			unset($newqueue);
297
			$newqueue = array();
298
			$currentqueuename = convert_real_interface_to_friendly_interface_name($items[2]);
299
			$currentqueueif = $items[2];
300
			$newqueue['name'] = $currentqueuename;
301
			$newqueue['interface'] = $items[2];
302
			$interfacestats[$currentqueueif][$currentqueuename] = &$newqueue;
303
		} else {
304
			if ($items[3] == "pkts:") {
305 5a0f6513 lucasheld
				preg_match('/pkts:\s+(\d+)\s+bytes:\s+(\d+)\s+dropped pkts:\s+(\d+)\s+bytes:\s+(\d+)/', $line, $matches);
306
				$newqueue["pkts"] = $matches[1];
307
				$newqueue["bytes"] = $matches[2];
308
				$newqueue["droppedpkts"] = $matches[3];
309
				$newqueue["droppedbytes"] = $matches[4];
310 0e2bed22 PiBa-NL
			}
311
			if ($items[3] == "qlength:") {
312
				$subitems = explode("/", substr($line, 13, 8));
313
				$newqueue["qlengthitems"] = trim($subitems[0]);
314
				$newqueue["qlengthsize"] = trim($subitems[1]);
315
				if (substr($line, 22, 8) == "borrows:") {
316
					$newqueue["borrows"] = trim(substr($line, 31, 7));
317
				}
318
				if (substr($line, 39, 9) == "suspends:") {
319
					$newqueue["suspends"] = trim(substr($line, 49, 7));
320
				}
321
			}
322
		}
323
	}
324
	$result['interfacestats'] = $interfacestats;
325
	return $result;
326
}
327 061f78b1 Bill Marquette
328 197bfe96 Ermal Luçi
/*
329 61e047a5 Phil Davis
 * I admit :) this is derived from xmlparse.inc StartElement()
330 197bfe96 Ermal Luçi
 */
331 61e047a5 Phil Davis
function &get_reference_to_me_in_config(&$mypath) {
332 197bfe96 Ermal Luçi
	global $config;
333
334 c6c398c6 jim-p
	init_config_arr(array('shaper'));
335
	$ptr = &$config['shaper'];
336 197bfe96 Ermal Luçi
	foreach ($mypath as $indeks) {
337 be228fd8 Stephen Jones
		if (!is_array($ptr)) {
338
			$ptr = array();
339
		}
340 41160d19 Stephen Jones
		if (!is_array($ptr['queue'])) {
341
			$ptr['queue'] = array();
342
		}
343
		if (!is_array($ptr['queue'][$indeks])) {
344
			$ptr['queue'][$indeks] = array();
345
		}
346 c6c398c6 jim-p
		$ptr = &$ptr['queue'][$indeks];
347 f5881023 Ermal Lu?i
	}
348 061f78b1 Bill Marquette
349 197bfe96 Ermal Luçi
	return $ptr;
350 061f78b1 Bill Marquette
}
351 d62ba478 Ermal Luçi
352 61e047a5 Phil Davis
function unset_object_by_reference(&$mypath) {
353 197bfe96 Ermal Luçi
	global $config;
354 061f78b1 Bill Marquette
355 c6c398c6 jim-p
	init_config_arr(array('shaper'));
356
	$ptr = &$config['shaper'];
357 f5881023 Ermal Lu?i
	for ($i = 0; $i < count($mypath) - 1; $i++) {
358 c6c398c6 jim-p
		$ptr = &$ptr['queue'][$mypath[$i]];
359 f5881023 Ermal Lu?i
	}
360 197bfe96 Ermal Luçi
	unset($ptr['queue'][$mypath[$i]]);
361
}
362 d62ba478 Ermal Luçi
363 61e047a5 Phil Davis
function &get_dn_reference_to_me_in_config(&$mypath) {
364 c25a6b6a Ermal Luçi
	global $config;
365
366 c6c398c6 jim-p
	init_config_arr(array('dnshaper'));
367
	$ptr = &$config['dnshaper'];
368 c25a6b6a Ermal Luçi
	foreach ($mypath as $indeks) {
369 c6c398c6 jim-p
		$ptr = &$ptr['queue'][$indeks];
370 f5881023 Ermal Lu?i
	}
371 c25a6b6a Ermal Luçi
372
	return $ptr;
373
}
374 d62ba478 Ermal Luçi
375 61e047a5 Phil Davis
function unset_dn_object_by_reference(&$mypath) {
376 c25a6b6a Ermal Luçi
	global $config;
377
378 c6c398c6 jim-p
	init_config_arr(array('dnshaper'));
379
	$ptr = &$config['dnshaper'];
380 f5881023 Ermal Lu?i
	for ($i = 0; $i < count($mypath) - 1; $i++) {
381 c6c398c6 jim-p
		$ptr = &$ptr['queue'][$mypath[$i]];
382 f5881023 Ermal Lu?i
	}
383 c25a6b6a Ermal Luçi
	unset($ptr['queue'][$mypath[$i]]);
384
}
385
386 61e047a5 Phil Davis
function clean_child_queues($type, $mypath) {
387 197bfe96 Ermal Luçi
	$ref = &get_reference_to_me_in_config($mypath);
388
389
	switch ($type) {
390 61e047a5 Phil Davis
		case 'HFSC':
391
			if (isset($ref['borrow'])) {
392
				unset($ref['borrow']);
393
			}
394
			if (isset($ref['hogs'])) {
395
				unset($ref['hogs']);
396
			}
397
			if (isset($ref['buckets'])) {
398
				unset($ref['buckets']);
399
			}
400
			break;
401
		case 'PRIQ':
402
			if (isset($ref['borrow'])) {
403
				unset($ref['borrow']);
404
			}
405
			if (isset($ref['bandwidth'])) {
406
				unset($ref['bandwidth']);
407
			}
408
			if (isset($ref['bandwidthtype'])) {
409
				unset($ref['bandwidthtype']);
410
			}
411
			/* fall through */
412
		case 'FAIRQ':
413
			if (isset($ref['borrow'])) {
414
				unset($ref['borrow']);
415
			}
416
			/* fall through */
417
		case 'CBQ':
418
			if (isset($ref['realtime'])) {
419
				unset($ref['realtime']);
420
			}
421
			if (isset($ref['realtime1'])) {
422
				unset($ref['realtime1']);
423
			}
424
			if (isset($ref['realtime2'])) {
425
				unset($ref['realtime2']);
426
			}
427
			if (isset($ref['realtime3'])) {
428
				unset($ref['realtime3']);
429
			}
430
			if (isset($ref['upperlimit'])) {
431
				unset($ref['upperlimit']);
432
			}
433
			if (isset($ref['upperlimit1'])) {
434
				unset($ref['upperlimit1']);
435
			}
436
			if (isset($ref['upperlimit2'])) {
437
				unset($ref['upperlimit2']);
438
			}
439
			if (isset($ref['upperlimit3'])) {
440
				unset($ref['upperlimit3']);
441
			}
442
			if (isset($ref['linkshare'])) {
443
				unset($ref['linkshare']);
444
			}
445
			if (isset($ref['linkshare1'])) {
446
				unset($ref['linkshare1']);
447
			}
448
			if (isset($ref['linkshare2'])) {
449
				unset($ref['linkshare2']);
450
			}
451
			if (isset($ref['linkshare3'])) {
452
				unset($ref['linkshare3']);
453
			}
454
			if (isset($ref['hogs'])) {
455
				unset($ref['hogs']);
456
			}
457
			if (isset($ref['buckets'])) {
458
				unset($ref['buckets']);
459
			}
460
			break;
461 197bfe96 Ermal Luçi
	}
462
}
463 061f78b1 Bill Marquette
464 61e047a5 Phil Davis
function get_bandwidthtype_scale($type) {
465 420b4538 Renato Botelho
	switch ($type) {
466 61e047a5 Phil Davis
		case "Gb":
467
			$factor = 1024 * 1024 * 1024;
468
			break;
469
		case "Mb":
470
			$factor = 1024 * 1024;
471
			break;
472
		case "Kb":
473
			$factor = 1024;
474
			break;
475
		case "b":
476
		default:
477
			$factor = 1;
478
			break;
479 420b4538 Renato Botelho
	}
480
	return intval($factor);
481 40de74f5 Ermal Luçi
}
482
483 45eeb038 Luiz Otavio O Souza
function get_bandwidth($bw, $scale, $obj) {
484 7140cb27 Stephen Jones
	$bw = (int) $bw;
485 2638ddec Luiz Otavio O Souza
	$pattern= "/(b|Kb|Mb|Gb|%)/";
486
	if (!preg_match($pattern, $scale, $match))
487
		return 0;
488
489
	switch ($match[1]) {
490
		case '%':
491 45eeb038 Luiz Otavio O Souza
			$objbw = ($bw / 100) * get_queue_bandwidth($obj);
492 2638ddec Luiz Otavio O Souza
			break;
493
		default:
494
			$objbw = $bw * get_bandwidthtype_scale($scale);
495
			break;
496
	}
497
498
	return floatval($objbw);
499
}
500
501 45eeb038 Luiz Otavio O Souza
/*
502
 * XXX - unused
503
 *
504 61e047a5 Phil Davis
function get_hfsc_bandwidth($object, $bw) {
505 40de74f5 Ermal Luçi
	$pattern= "/[0-9]+/";
506 61e047a5 Phil Davis
	if (preg_match($pattern, $bw, $match)) {
507 420b4538 Renato Botelho
		$bw_1 = $match[1];
508 61e047a5 Phil Davis
	} else {
509 420b4538 Renato Botelho
		return 0;
510 61e047a5 Phil Davis
	}
511 420b4538 Renato Botelho
	$pattern= "/(b|Kb|Mb|Gb|%)/";
512
	if (preg_match($pattern, $bw, $match)) {
513
		switch ($match[1]) {
514 61e047a5 Phil Davis
			case '%':
515 45eeb038 Luiz Otavio O Souza
				$bw_1 = ($bw_1 / 100) * get_interface_bandwidth($object);
516 61e047a5 Phil Davis
				break;
517
			default:
518
				$bw_1 = $bw_1 * get_bandwidthtype_scale($match[0]);
519
				break;
520 420b4538 Renato Botelho
		}
521 3a54efed Ermal Luçi
		return floatval($bw_1);
522 61e047a5 Phil Davis
	} else {
523 420b4538 Renato Botelho
		return 0;
524 61e047a5 Phil Davis
	}
525 40de74f5 Ermal Luçi
}
526 45eeb038 Luiz Otavio O Souza
*/
527
528
function get_queue_bandwidth($obj) {
529 b1972170 Reid Linnemann
	$bw = (int)$obj->GetBandwidth();
530 45eeb038 Luiz Otavio O Souza
	$scale = $obj->GetBwscale();
531
532
	$pattern= "/(b|Kb|Mb|Gb|%)/";
533
	if (!preg_match($pattern, $scale, $match))
534
		return 0;
535
536
	switch ($match[1]) {
537
		case '%':
538 734848b6 Viktor G
			if (method_exists($obj, 'GetParent')) {
539
				$getobjbw = get_queue_bandwidth($obj->GetParent());
540
			} else {
541
				$getobjbw = $obj->bandwidth;
542
			}
543
			$objbw = ($bw / 100) * $getobjbw;
544 45eeb038 Luiz Otavio O Souza
			break;
545
		default:
546
			$objbw = $bw * get_bandwidthtype_scale($scale);
547
			break;
548
	}
549
550
	return floatval($objbw);
551
}
552 40de74f5 Ermal Luçi
553 61e047a5 Phil Davis
function get_interface_bandwidth($object) {
554 40de74f5 Ermal Luçi
	global $altq_list_queues;
555
556 420b4538 Renato Botelho
	$int = $object->GetInterface();
557 c6c398c6 jim-p
	if (isset($altq_list_queues[$int])) {
558
		$altq = &$altq_list_queues[$int];
559 b1972170 Reid Linnemann
		$bw_3 = (int)$altq->GetBandwidth();
560 4de8f7ba Phil Davis
		$bw_3 = $bw_3 * get_bandwidthtype_scale($altq->GetBwscale());
561 3a54efed Ermal Luçi
		return floatval($bw_3);
562 61e047a5 Phil Davis
	} else {
563 f5881023 Ermal Lu?i
		return 0;
564 61e047a5 Phil Davis
	}
565 40de74f5 Ermal Luçi
}
566
567
/*
568
 * This is duplicated here since we cannot include guiconfig.inc.
569
 * Including it makes all stuff break.
570
 */
571 61e047a5 Phil Davis
function shaper_do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors) {
572 40de74f5 Ermal Luçi
573 420b4538 Renato Botelho
	/* check for bad control characters */
574
	foreach ($postdata as $pn => $pd) {
575
		if (is_string($pd) && preg_match("/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/", $pd)) {
576
			$input_errors[] = sprintf(gettext("The field '%s' contains invalid characters."), $pn);
577
		}
578
	}
579
580
	for ($i = 0; $i < count($reqdfields); $i++) {
581
		if ($postdata[$reqdfields[$i]] == "") {
582
			$input_errors[] = sprintf(gettext("The field '%s' is required."), $reqdfieldsn[$i]);
583
		}
584
	}
585 40de74f5 Ermal Luçi
}
586
587 61e047a5 Phil Davis
function cleanup_queue_from_rules($queue) {
588 197bfe96 Ermal Luçi
	global $config;
589 061f78b1 Bill Marquette
590 402012d9 Viktor G
	foreach ($config['filter']['rule'] as & $rule) {
591 61e047a5 Phil Davis
		if ($rule['defaultqueue'] == $queue) {
592 197bfe96 Ermal Luçi
			unset($rule['defaultqueue']);
593 e2456a7a jim-p
			if (isset($rule['ackqueue'])) {
594 402012d9 Viktor G
				unset($rule['ackqueue']);
595
			}
596 61e047a5 Phil Davis
		}
597
		if ($rule['ackqueue'] == $queue) {
598 197bfe96 Ermal Luçi
			unset($rule['ackqueue']);
599 61e047a5 Phil Davis
		}
600 197bfe96 Ermal Luçi
	}
601 061f78b1 Bill Marquette
}
602
603 61e047a5 Phil Davis
function cleanup_dnqueue_from_rules($queue) {
604 c25a6b6a Ermal Luçi
	global $config;
605
606 402012d9 Viktor G
	foreach ($config['filter']['rule'] as & $rule) {
607 61e047a5 Phil Davis
		if ($rule['dnpipe'] == $queue) {
608 c25a6b6a Ermal Luçi
			unset($rule['dnpipe']);
609 61e047a5 Phil Davis
		}
610
		if ($rule['pdnpipe'] == $queue) {
611 c25a6b6a Ermal Luçi
			unset($rule['pdnpipe']);
612 61e047a5 Phil Davis
		}
613 c25a6b6a Ermal Luçi
	}
614
}
615
616 402012d9 Viktor G
function rename_queue_in_rules($name, $newname) {
617
	global $config;
618
619
	foreach ($config['filter']['rule'] as & $rule) {
620
		if ($rule['defaultqueue'] == $name) {
621
			$rule['defaultqueue'] = $newname;
622
		}
623
		if ($rule['ackqueue'] == $name) {
624
			$rule['ackqueue'] = $newname;
625
		}
626
	}
627
}
628
629
function rename_dnqueue_in_rules($name, $newname) {
630
	global $config;
631
632
	foreach ($config['filter']['rule'] as & $rule) {
633
		if ($rule['dnpipe'] == $name) {
634
			$rule['dnpipe'] = $newname;
635
		}
636
		if ($rule['pdnpipe'] == $name) {
637
			$rule['pdnpipe'] = $newname;
638
		}
639
	}
640
}
641
642 197bfe96 Ermal Luçi
class altq_root_queue {
643 f5881023 Ermal Lu?i
	var $interface;
644
	var $tbrconfig ;
645
	var $bandwidth;
646 bfc94df0 Phil Davis
	var $bandwidthtype; /* b, Kb, Mb, Gb, % */
647 f5881023 Ermal Lu?i
	var $scheduler;
648
	var $qlimit;
649
	var $queues = array();
650
	var $qenabled = false;
651
	var $link;
652
653 d6fa899d Phil Davis
	/* Accessor functions */
654 197bfe96 Ermal Luçi
	function GetDefaultQueuePresent() {
655 f61dc8e6 Ermal
		if (!empty($this->queues)) {
656
			foreach ($this->queues as $q) {
657 61e047a5 Phil Davis
				if ($q->GetDefault()) {
658 f61dc8e6 Ermal
					return true;
659 61e047a5 Phil Davis
				}
660 f61dc8e6 Ermal
			}
661
		}
662
663
		return false;
664 197bfe96 Ermal Luçi
	}
665
	function SetLink($link) {
666
		$this->link = $link;
667
	}
668
	function GetLink() {
669
		return $this->link;
670 420b4538 Renato Botelho
	}
671 197bfe96 Ermal Luçi
	function GetEnabled() {
672
		return $this->qenabled;
673
	}
674 92125c97 Ermal Luçi
	function SetEnabled($value) {
675 197bfe96 Ermal Luçi
		$this->qenabled = $value;
676
	}
677 70b139a3 Chris Buechler
	function CanHaveChildren() {
678 61e047a5 Phil Davis
		if ($this->GetScheduler() == "CODELQ") {
679 8edaa92c Ermal
			return false;
680 61e047a5 Phil Davis
		} else {
681 8edaa92c Ermal
			return true;
682 61e047a5 Phil Davis
		}
683 197bfe96 Ermal Luçi
	}
684
	function CanBeDeleted() {
685
		return false;
686
	}
687
	function GetQname() {
688
		return $this->interface;
689
	}
690
	function SetQname($name) {
691
		$this->interface = trim($name);
692
	}
693 92125c97 Ermal Luçi
	function GetInterface() {
694 f5881023 Ermal Lu?i
		return $this->interface;
695 92125c97 Ermal Luçi
	}
696
	function SetInterface($name) {
697 f5881023 Ermal Lu?i
		$this->interface = trim($name);
698 92125c97 Ermal Luçi
	}
699
	function GetTbrConfig() {
700 f5881023 Ermal Lu?i
		return $this->tbrconfig;
701 92125c97 Ermal Luçi
	}
702
	function SetTbrConfig($tbrconfig) {
703 f5881023 Ermal Lu?i
		$this->tbrconfig = $tbrconfig;
704 92125c97 Ermal Luçi
	}
705
	function GetBandwidth() {
706 f5881023 Ermal Lu?i
		return $this->bandwidth;
707 92125c97 Ermal Luçi
	}
708
	function SetBandwidth($bw) {
709 f5881023 Ermal Lu?i
		$this->bandwidth = $bw;
710 92125c97 Ermal Luçi
	}
711
	function GetBwscale() {
712 f5881023 Ermal Lu?i
		return $this->bandwidthtype;
713 92125c97 Ermal Luçi
	}
714 9abbcb4b Viktor G
	function FormGetBwscale() {
715
		if ($this->GetBwscale()) {
716
			$bwscale = $this->GetBwscale();
717
		} else {
718
			$bwscale = 'Mb';
719
		}
720
		return $bwscale;
721
	}
722 92125c97 Ermal Luçi
	function SetBwscale($bwscale) {
723 f5881023 Ermal Lu?i
		$this->bandwidthtype = $bwscale;
724 92125c97 Ermal Luçi
	}
725
	function GetScheduler() {
726 f5881023 Ermal Lu?i
		return $this->scheduler;
727 92125c97 Ermal Luçi
	}
728
	function SetScheduler($scheduler) {
729 f5881023 Ermal Lu?i
		$this->scheduler = trim($scheduler);
730 92125c97 Ermal Luçi
	}
731 197bfe96 Ermal Luçi
	function GetQlimit() {
732
		return $this->qlimit;
733
	}
734
	function SetQlimit($limit) {
735
		$this->qlimit = $limit;
736
	}
737 f5881023 Ermal Lu?i
738 bfc94df0 Phil Davis
	function GetBwscaleText() {
739
		switch ($this->bandwidthtype) {
740
			case "b":
741
				$bwscaletext = "Bit/s";
742
				break;
743
			case "Kb":
744
				$bwscaletext = "Kbit/s";
745
				break;
746
			case "Mb":
747
				$bwscaletext = "Mbit/s";
748
				break;
749
			case "Gb":
750
				$bwscaletext = "Gbit/s";
751
				break;
752
			default:
753
				/* For others that do not need translating like % */
754
				$bwscaletext = $this->bandwidthtype;
755
				break;
756
		}
757
		return $bwscaletext;
758
	}
759
760 45eeb038 Luiz Otavio O Souza
	function CheckBandwidth($bw, $bwtype) {
761 b1972170 Reid Linnemann
		$bw = (int)$bw;
762 45eeb038 Luiz Otavio O Souza
		$sum = $this->GetTotalBw();
763 b0f0993d Viktor G
		if ($sum > ($bw * get_bandwidthtype_scale($bwtype))) {
764 45eeb038 Luiz Otavio O Souza
			return 1;
765 b0f0993d Viktor G
		}
766 45eeb038 Luiz Otavio O Souza
		foreach ($this->queues as $q) {
767 b0f0993d Viktor G
			if ($q->CheckBandwidth(0, '')) {
768 45eeb038 Luiz Otavio O Souza
				return 1;
769 b0f0993d Viktor G
			}
770 45eeb038 Luiz Otavio O Souza
		}
771
772
		return 0;
773
	}
774
775
	function GetTotalBw($qignore = NULL) {
776 2638ddec Luiz Otavio O Souza
		$sum = 0;
777
		foreach ($this->queues as $q) {
778 b0f0993d Viktor G
			if (($qignore != NULL) && ($qignore == $q)) {
779 45eeb038 Luiz Otavio O Souza
				continue;
780 b0f0993d Viktor G
			}
781 45eeb038 Luiz Otavio O Souza
			$sum += get_bandwidth($q->GetBandwidth(), $q->GetBwscale(), $this);
782 2638ddec Luiz Otavio O Souza
		}
783
784
		return $sum;
785
	}
786
787 197bfe96 Ermal Luçi
	function validate_input($data, &$input_errors) {
788 ce0117f7 Colin Fleming
789 2c072899 jim-p
		$reqdfields[] = "bandwidth";
790 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidth");
791 2c072899 jim-p
		$reqdfields[] = "bandwidthtype";
792 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidthtype");
793 ce0117f7 Colin Fleming
794 40de74f5 Ermal Luçi
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
795 ce0117f7 Colin Fleming
796 b1972170 Reid Linnemann
		if ($data['bandwidth'] == null) {
797 2638ddec Luiz Otavio O Souza
			$input_errors[] = gettext("Bandwidth must be set.  This is usually the interface speed.");
798 b1972170 Reid Linnemann
		} else {
799
			if ((!is_numeric($data['bandwidth']))) {
800
				$input_errors[] = gettext("Bandwidth must be an integer.");
801
			}
802
			if ((int)$data['bandwidth'] < 0) {
803
				$input_errors[] = gettext("Bandwidth cannot be negative.");
804
			}
805 61e047a5 Phil Davis
		}
806 45eeb038 Luiz Otavio O Souza
		if ($data['bandwidthtype'] == "%") {
807
			if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0) {
808
				$input_errors[] = gettext("Bandwidth in percentage should be between 1 and 100.");
809
			}
810
		}
811 662abcf1 Viktor G
		if ($this->CheckBandwidth($data['bandwidth'], $data['bandwidthtype'])) {
812 45eeb038 Luiz Otavio O Souza
			$input_errors[] = "The sum of child bandwidth is higher than parent.";
813 662abcf1 Viktor G
		}
814 b1972170 Reid Linnemann
		if (($data['qlimit'] != null) && ($data['scheduler'] == 'CODELQ')) {
815 662abcf1 Viktor G
			$input_errors[] = gettext("CODELQ scheduler doesn't support Qlimit parameter.");
816
		}
817 b1972170 Reid Linnemann
		if (($data['qlimit'] != null) && (!is_numeric($data['qlimit']))) {
818 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("Qlimit must be an integer.");
819 61e047a5 Phil Davis
		}
820 b1972170 Reid Linnemann
		if (($data['qlimit'] != null) && (int)$data['qlimit'] < 1) {
821 794195d1 Phil Davis
			$input_errors[] = gettext("Qlimit must be positive.");
822 61e047a5 Phil Davis
		}
823 b1972170 Reid Linnemann
		if (($data['tbrconfig'] != null) && (!is_numeric($data['tbrconfig']))) {
824 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("Tbrsize must be an integer.");
825 61e047a5 Phil Davis
		}
826 b1972170 Reid Linnemann
		if (($data['tbrconfig'] != null) && (int)$data['tbrconfig'] < 1) {
827 794195d1 Phil Davis
			$input_errors[] = gettext("Tbrsize must be positive.");
828 61e047a5 Phil Davis
		}
829 92125c97 Ermal Luçi
	}
830 197bfe96 Ermal Luçi
831
	/* Implement this to shorten some code on the frontend page */
832 f5881023 Ermal Lu?i
	function ReadConfig(&$conf) {
833 61e047a5 Phil Davis
		if (isset($conf['tbrconfig'])) {
834 f5881023 Ermal Lu?i
			$this->SetTbrConfig($conf['tbrconfig']);
835 61e047a5 Phil Davis
		} else {
836 06f3e447 Ermal
			$this->SetTbrConfig($conf['tbrconfig']);
837 61e047a5 Phil Davis
		}
838 1941345c Ermal
		$this->SetBandwidth($conf['bandwidth']);
839 61e047a5 Phil Davis
		if ($conf['bandwidthtype'] <> "") {
840 1941345c Ermal
			$this->SetBwscale($conf['bandwidthtype']);
841 61e047a5 Phil Davis
		}
842 197bfe96 Ermal Luçi
		if (isset($conf['scheduler'])) {
843 f5881023 Ermal Lu?i
			if ($this->GetScheduler() != $conf['scheduler']) {
844
				foreach ($this->queues as $q) {
845
					clean_child_queues($conf['scheduler'], $this->GetLink());
846
					$q->clean_queue($conf['scheduler']);
847 061f78b1 Bill Marquette
				}
848
			}
849 f5881023 Ermal Lu?i
			$this->SetScheduler($conf['scheduler']);
850
		}
851 61e047a5 Phil Davis
		if (isset($conf['qlimit']) && $conf['qlimit'] <> "") {
852 197bfe96 Ermal Luçi
			$this->SetQlimit($conf['qlimit']);
853 61e047a5 Phil Davis
		} else {
854 06f3e447 Ermal
			$this->SetQlimit("");
855 61e047a5 Phil Davis
		}
856
		if (isset($conf['name'])) {
857 420b4538 Renato Botelho
			$this->SetQname($conf['name']);
858 61e047a5 Phil Davis
		}
859
		if (!empty($conf['enabled'])) {
860 f5881023 Ermal Lu?i
			$this->SetEnabled($conf['enabled']);
861 61e047a5 Phil Davis
		} else {
862 ea25d26d Ermal Lu?i
			$this->SetEnabled("");
863 61e047a5 Phil Davis
		}
864 197bfe96 Ermal Luçi
	}
865 f5881023 Ermal Lu?i
866 a843b04f Ermal Luçi
	function copy_queue($interface, &$cflink) {
867 420b4538 Renato Botelho
		$cflink['interface'] = $interface;
868
		$cflink['name'] = $interface;
869
		$cflink['scheduler'] = $this->GetScheduler();
870
		$cflink['bandwidth'] = $this->GetBandwidth();
871
		$cflink['bandwidthtype'] = $this->GetBwscale();
872
		$cflink['qlimit'] = $this->GetQlimit();
873
		$cflink['tbrconfig'] = $this->GetTbrConfig();
874
		$cflink['enabled'] = $this->GetEnabled();
875 a843b04f Ermal Luçi
		if (is_array($this->queues)) {
876
			$cflink['queue'] = array();
877
			foreach ($this->queues as $q) {
878
				$cflink['queue'][$q->GetQname()] = array();
879 dbf2dde4 Renato Botelho
				$q->copy_queue($interface, $cflink['queue'][$q->GetQname()]);
880 a843b04f Ermal Luçi
			}
881 92125c97 Ermal Luçi
		}
882 061f78b1 Bill Marquette
	}
883
884 ea51e9f8 Renato Botelho
	function &get_queue_list(&$q = null) {
885 f5881023 Ermal Lu?i
		$qlist = array();
886 b7ff5e40 Scott Ullrich
887 8484586f Ermal
		//$qlist[$this->GetQname()] = & $this;
888 f5881023 Ermal Lu?i
		if (is_array($this->queues)) {
889 61e047a5 Phil Davis
			foreach ($this->queues as $queue) {
890 ea51e9f8 Renato Botelho
				$queue->get_queue_list($qlist);
891 61e047a5 Phil Davis
			}
892 fe93b17b Ermal Luçi
		}
893 f5881023 Ermal Lu?i
		return $qlist;
894
	}
895 fe93b17b Ermal Luçi
896 f5881023 Ermal Lu?i
	function &add_queue($interface, &$queue, &$path, &$input_errors) {
897 92125c97 Ermal Luçi
898 61e047a5 Phil Davis
		if (!is_array($this->queues)) {
899 f5881023 Ermal Lu?i
			$this->queues = array();
900 61e047a5 Phil Davis
		}
901 f5881023 Ermal Lu?i
902
		switch ($this->GetScheduler()) {
903 61e047a5 Phil Davis
			case "PRIQ":
904 5c4fcabc Renato Botelho
				$__tmp_q = new priq_queue(); $q =& $__tmp_q;
905 61e047a5 Phil Davis
				break;
906
			case "HFSC":
907 5c4fcabc Renato Botelho
				$__tmp_q = new hfsc_queue(); $q =& $__tmp_q;
908 61e047a5 Phil Davis
				break;
909
			case "CBQ":
910 5c4fcabc Renato Botelho
				$__tmp_q = new cbq_queue(); $q =& $__tmp_q;
911 61e047a5 Phil Davis
				break;
912
			case "FAIRQ":
913 5c4fcabc Renato Botelho
				$__tmp_q = new fairq_queue(); $q =& $__tmp_q;
914 61e047a5 Phil Davis
				break;
915
			default:
916
				/* XXX: but should not happen anyway */
917
				return;
918
				break;
919 f5881023 Ermal Lu?i
		}
920
		$q->SetLink($path);
921
		$q->SetInterface($this->GetInterface());
922
		$q->SetEnabled("on");
923 ea51e9f8 Renato Botelho
		$q->SetParent($this);
924 f5881023 Ermal Lu?i
		$q->ReadConfig($queue);
925
		$q->validate_input($queue, $input_errors);
926 197bfe96 Ermal Luçi
927 420b4538 Renato Botelho
		$this->queues[$q->GetQname()] = &$q;
928 f5881023 Ermal Lu?i
		ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
929
		if (is_array($queue['queue'])) {
930
			foreach ($queue['queue'] as $key1 => $que) {
931
				array_push($path, $key1);
932 ea51e9f8 Renato Botelho
				$q->add_queue($q->GetInterface(), $que, $path, $input_errors);
933 f5881023 Ermal Lu?i
				array_pop($path);
934
			}
935
		}
936
937
		return $q;
938
	}
939
940
	/* interface here might be optional */
941
	function &find_queue($interface, $qname) {
942
		if ($qname == $this->GetQname()) {
943
			return $this;
944 420b4538 Renato Botelho
		}
945 f5881023 Ermal Lu?i
		foreach ($this->queues as $q) {
946
			$result =& $q->find_queue("", $qname);
947 61e047a5 Phil Davis
			if ($result) {
948 f5881023 Ermal Lu?i
				return $result;
949 61e047a5 Phil Davis
			}
950 f5881023 Ermal Lu?i
		}
951
	}
952 197bfe96 Ermal Luçi
953
	function &find_parentqueue($interface, $qname) {
954
		if ($qname == $interface) {
955 4de8f7ba Phil Davis
			$result = NULL;
956 420b4538 Renato Botelho
		} else if ($this->queues[$qname]) {
957 197bfe96 Ermal Luçi
			$result = $this;
958
		} else if ($this->GetScheduler() <> "PRIQ") {
959
			foreach ($this->queues as $q) {
960
				$result = $q->find_parentqueue("", $qname);
961 61e047a5 Phil Davis
				if ($result) {
962 197bfe96 Ermal Luçi
					return $result;
963 61e047a5 Phil Davis
				}
964 b7ff5e40 Scott Ullrich
			}
965 061f78b1 Bill Marquette
		}
966
	}
967
968 197bfe96 Ermal Luçi
	function build_tree() {
969 057399e4 Ermal Luçi
		global $shaperIFlist;
970
971 420b4538 Renato Botelho
		$tree = " <li><a href=\"firewall_shaper.php?interface=".$this->GetInterface()."&amp;queue=". $this->GetInterface()."&amp;action=show";
972 057399e4 Ermal Luçi
		$tree .= "\">" . $shaperIFlist[$this->GetInterface()] . "</a>";
973 197bfe96 Ermal Luçi
		if (is_array($this->queues)) {
974
			$tree .= "<ul>";
975 4de8f7ba Phil Davis
			foreach ($this->queues as $q) {
976 197bfe96 Ermal Luçi
				$tree .= $q->build_tree();
977
			}
978 61e047a5 Phil Davis
			$tree .= "</ul>";
979 197bfe96 Ermal Luçi
		}
980
		$tree .= "</li>";
981
		return $tree;
982
	}
983 ce0117f7 Colin Fleming
984 420b4538 Renato Botelho
	function delete_queue() {
985 402012d9 Viktor G
		foreach ($this->queues as $q) {
986 420b4538 Renato Botelho
			$q->delete_queue();
987 402012d9 Viktor G
		}
988 197bfe96 Ermal Luçi
		unset_object_by_reference($this->GetLink());
989 420b4538 Renato Botelho
	}
990 92125c97 Ermal Luçi
991 b0262cb2 Ermal Luçi
	function delete_all() {
992 420b4538 Renato Botelho
		if (count($this->queues)) {
993
			foreach ($this->queues as $q) {
994
				$q->delete_all();
995
				unset_object_by_reference($q->GetLink());
996
				unset($q);
997
			}
998
			unset($this->queues);
999
		}
1000
	}
1001 b0262cb2 Ermal Luçi
1002 92125c97 Ermal Luçi
	/*
1003
	 * First it spits:
1004
	 * altq on $interface ..............
1005 6990ad35 Phil Davis
	 *	then it goes like
1006
	 *	foreach ($queues as $qkey => $queue) {
1007
	 *		this->queues[$qkey]->build_rule();
1008
	 *	}
1009 92125c97 Ermal Luçi
	 */
1010 9d0b0635 Ermal
	function build_rules(&$default = false) {
1011 34a3694b Ermal
		if (count($this->queues) > 0 && $this->GetEnabled() == "on") {
1012 ef8fca71 Ermal
			$default = false;
1013 4de8f7ba Phil Davis
			$rules = " altq on " . get_real_interface($this->GetInterface());
1014 61e047a5 Phil Davis
			if ($this->GetScheduler()) {
1015 f5881023 Ermal Lu?i
				$rules .= " ".strtolower($this->GetScheduler());
1016 61e047a5 Phil Davis
			}
1017
			if ($this->GetQlimit() > 0) {
1018 a061ddb9 Chris Buechler
				$rules .= " qlimit " . $this->GetQlimit() . " ";
1019 61e047a5 Phil Davis
			}
1020 1941345c Ermal
			if ($this->GetBandwidth()) {
1021 f5881023 Ermal Lu?i
				$rules .= " bandwidth ".trim($this->GetBandwidth());
1022 61e047a5 Phil Davis
				if ($this->GetBwscale()) {
1023 1941345c Ermal
					$rules .= $this->GetBwscale();
1024 61e047a5 Phil Davis
				}
1025 1941345c Ermal
			}
1026 61e047a5 Phil Davis
			if ($this->GetTbrConfig()) {
1027 f5881023 Ermal Lu?i
				$rules .= " tbrsize ".$this->GetTbrConfig();
1028 61e047a5 Phil Davis
			}
1029 92125c97 Ermal Luçi
			if (count($this->queues)) {
1030 f5881023 Ermal Lu?i
				$i = count($this->queues);
1031
				$rules .= " queue { ";
1032
				foreach ($this->queues as $qkey => $qnone) {
1033
					if ($i > 1) {
1034
						$i--;
1035
						$rules .= " {$qkey}, ";
1036 61e047a5 Phil Davis
					} else {
1037 f5881023 Ermal Lu?i
						$rules .= " {$qkey} ";
1038 61e047a5 Phil Davis
					}
1039 f5881023 Ermal Lu?i
				}
1040
				$rules .= " } \n";
1041
				foreach ($this->queues as $q) {
1042 9d0b0635 Ermal
					$rules .= $q->build_rules($default);
1043 f5881023 Ermal Lu?i
				}
1044 92125c97 Ermal Luçi
			}
1045 8edaa92c Ermal
1046 ef8fca71 Ermal
			if ($default == false) {
1047 e8c516a0 Phil Davis
				$error = sprintf(gettext("SHAPER: no default queue specified for interface %s."), $this->GetInterface()) . " " . gettext("The interface queue will be enforced as default.");
1048 8633930d Ermal
				file_notice("Shaper", $error, "Error occurred", "");
1049
				unset($error);
1050 ef8fca71 Ermal
				return "\n";
1051 420b4538 Renato Botelho
			}
1052 ef8fca71 Ermal
			$frule .= $rules;
1053 8edaa92c Ermal
		} else if ($this->GetEnabled() == "on" && $this->GetScheduler() == "CODELQ") {
1054 4de8f7ba Phil Davis
			$rules = " altq on " . get_real_interface($this->GetInterface());
1055 61e047a5 Phil Davis
			if ($this->GetScheduler()) {
1056 8edaa92c Ermal
				$rules .= " ".strtolower($this->GetScheduler());
1057 61e047a5 Phil Davis
			}
1058
			if ($this->GetQlimit() > 0) {
1059 8edaa92c Ermal
				$rules .= " ( qlimit " . $this->GetQlimit() . " ) ";
1060 61e047a5 Phil Davis
			}
1061 8edaa92c Ermal
			if ($this->GetBandwidth()) {
1062
				$rules .= " bandwidth ".trim($this->GetBandwidth());
1063 61e047a5 Phil Davis
				if ($this->GetBwscale()) {
1064 8edaa92c Ermal
					$rules .= $this->GetBwscale();
1065 61e047a5 Phil Davis
				}
1066 8edaa92c Ermal
			}
1067 61e047a5 Phil Davis
			if ($this->GetTbrConfig()) {
1068 8edaa92c Ermal
				$rules .= " tbrsize ".$this->GetTbrConfig();
1069 61e047a5 Phil Davis
			}
1070 8edaa92c Ermal
1071
			$rules .= " queue";
1072 197bfe96 Ermal Luçi
		}
1073 8edaa92c Ermal
1074 197bfe96 Ermal Luçi
		$rules .= " \n";
1075 92125c97 Ermal Luçi
		return $rules;
1076
	}
1077 197bfe96 Ermal Luçi
1078
	function build_javascript() {
1079 f5881023 Ermal Lu?i
		$javascript = "<script type=\"text/javascript\">";
1080 ee02550a Michele Di Maria
		$javascript .= "//<![CDATA[\n";
1081 f5881023 Ermal Lu?i
		$javascript .= "function mySuspend() {";
1082 01890f6a Ermal
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null) ";
1083
		$javascript .= "document.layers['shaperarea'].visibility = 'hidden'; ";
1084 f5881023 Ermal Lu?i
		$javascript .= "else if (document.all)";
1085
		$javascript .= "document.all['shaperarea'].style.visibility = 'hidden';";
1086
		$javascript .= "}";
1087
1088
		$javascript .= "function myResume() {";
1089 01890f6a Ermal
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null) ";
1090 f5881023 Ermal Lu?i
		$javascript .= "document.layers['shaperarea'].visibility = 'visible';";
1091 01890f6a Ermal
		$javascript .= "else if (document.all) ";
1092 f5881023 Ermal Lu?i
		$javascript .= "document.all['shaperarea'].style.visibility = 'visible';";
1093
		$javascript .= "}";
1094 0fa05f45 Colin Fleming
		$javascript .= "//]]>";
1095 f5881023 Ermal Lu?i
		$javascript .= "</script>";
1096
1097
		return $javascript;
1098 92125c97 Ermal Luçi
	}
1099 ce0117f7 Colin Fleming
1100 92125c97 Ermal Luçi
	function build_shortform() {
1101 f5881023 Ermal Lu?i
		global $g;
1102
1103
		$altq =& $this;
1104 d17c4ee9 Stephen Beaver
1105 61e047a5 Phil Davis
		if ($altq) {
1106 f5881023 Ermal Lu?i
			$scheduler = ": " . $altq->GetScheduler();
1107 61e047a5 Phil Davis
		}
1108 f5881023 Ermal Lu?i
1109 b28e1512 Stephen Beaver
		$form = '<dl class="dl-horizontal">';
1110
		$form .= '	<dt>';
1111
		$form .= '		<a href="firewall_shaper.php?interface=' . $this->GetInterface() . '&amp;queue=' . $this->GetQname() . '&amp;action=show">' . $shaperIFlist[$this->GetInterface()] . '</a>';
1112
		$form .= '	</dt>';
1113
		$form .= '	<dd>';
1114 d17c4ee9 Stephen Beaver
		$form .=		$scheduler;
1115 b28e1512 Stephen Beaver
		$form .= '	</dd>';
1116 d17c4ee9 Stephen Beaver
1117 b28e1512 Stephen Beaver
		$form .= '	<dt>';
1118 d17c4ee9 Stephen Beaver
		$form .=		'Bandwidth';
1119 b28e1512 Stephen Beaver
		$form .= '	</dt>';
1120
		$form .= '	<dd>';
1121 bfc94df0 Phil Davis
		$form .=		$this->GetBandwidth() . '&nbsp;' . $this->GetBwscaleText();
1122 b28e1512 Stephen Beaver
		$form .= '	</dd>';
1123 d17c4ee9 Stephen Beaver
1124
		$form .= '	<dt>';
1125 b28e1512 Stephen Beaver
		$form .= 'Disable';
1126
		$form .= '	<dt>';
1127
		$form .= '	<dd>';
1128
1129 27d6a45b jim-p
		$form .= '<a class="btn btn-danger btn-xs" href="firewall_shaper_queues.php?interface=';
1130 b28e1512 Stephen Beaver
		$form .= $this->GetInterface() . '&amp;queue=';
1131
		$form .= $this->GetQname() . '&amp;action=delete">';
1132 27d6a45b jim-p
		$form .= '<i class="fa fa-trash icon-embed-btn"></i>';
1133
		$form .= gettext("Remove shaper from this interface") . '</a>';
1134 b28e1512 Stephen Beaver
1135 d17c4ee9 Stephen Beaver
		$form .= '	</dd>';
1136
1137
		$form .= '</dl>';
1138
1139 f5881023 Ermal Lu?i
		return $form;
1140 92125c97 Ermal Luçi
1141
	}
1142 aef9d8fe Stephen Beaver
1143 f5881023 Ermal Lu?i
	/*
1144 ce0117f7 Colin Fleming
	 * For requesting the parameters of the root queues
1145 f5881023 Ermal Lu?i
	 * to the user like the traffic wizard does.
1146 806942d0 Stephen Beaver
	 */
1147 420b4538 Renato Botelho
	function build_form() {
1148 806942d0 Stephen Beaver
1149 27d6a45b jim-p
		$sform = new Form();
1150 806942d0 Stephen Beaver
1151 a51c7c7f Stephen Beaver
		$sform->setAction("firewall_shaper.php");
1152
1153 aef9d8fe Stephen Beaver
		$section = new Form_Section(null);
1154 806942d0 Stephen Beaver
1155 aef9d8fe Stephen Beaver
		$section->addInput(new Form_Checkbox(
1156
			'enabled',
1157
			'Enable/Disable',
1158
			'Enable/disable discipline and its children',
1159
			($this->GetEnabled() == "on"),
1160
			'on'
1161
		));
1162 806942d0 Stephen Beaver
1163 aef9d8fe Stephen Beaver
		$section->addInput(new Form_StaticText(
1164 40dcb4b6 Phil Davis
			'*Name',
1165 aef9d8fe Stephen Beaver
			$this->GetQname()
1166
		));
1167 806942d0 Stephen Beaver
1168 aef9d8fe Stephen Beaver
		$section->addInput(new Form_Select(
1169
			'scheduler',
1170
			'Scheduler Type',
1171
			$this->GetScheduler(),
1172 806942d0 Stephen Beaver
			array('HFSC' => 'HFSC',
1173 aef9d8fe Stephen Beaver
				  'CBQ' => 'CBQ',
1174
				  'FAIRQ' => 'FAIRQ',
1175
				  'CODELQ' => 'CODELQ',
1176
				  'PRIQ' => 'PRIQ')
1177 530e4707 NOYB
		))->setHelp('Changing this changes all child queues! Beware information can be lost.');
1178 806942d0 Stephen Beaver
1179 aef9d8fe Stephen Beaver
		$group = new Form_group('Bandwidth');
1180 806942d0 Stephen Beaver
1181 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
1182
			'bandwidth',
1183
			null,
1184
			'number',
1185
			$this->GetBandwidth()
1186
		));
1187 806942d0 Stephen Beaver
1188 aef9d8fe Stephen Beaver
		$group->add(new Form_Select(
1189
			'bandwidthtype',
1190
			null,
1191 9abbcb4b Viktor G
			$this->FormGetBwscale(),
1192 bfc94df0 Phil Davis
			array('Kb' => 'Kbit/s',
1193
				  'Mb' => 'Mbit/s',
1194
				  'Gb' => 'Gbit/s',
1195
				  'b' => 'Bit/s',
1196 820519e5 Stephen Beaver
				  '%' => '%')
1197 aef9d8fe Stephen Beaver
		));
1198 806942d0 Stephen Beaver
1199 aef9d8fe Stephen Beaver
		$section->add($group);
1200 806942d0 Stephen Beaver
1201 aef9d8fe Stephen Beaver
		$section->addInput(new Form_Input(
1202
			'qlimit',
1203
			'Queue Limit',
1204
			'number',
1205
			$this->GetQlimit()
1206
		));
1207 806942d0 Stephen Beaver
1208 aef9d8fe Stephen Beaver
		$section->addInput(new Form_Input(
1209
			'tbrconfig',
1210 e643627c Ben Cook
			'TBR Size',
1211 aef9d8fe Stephen Beaver
			'number',
1212
			$this->GetTbrConfig()
1213
		))->setHelp('Adjusts the size, in bytes, of the token bucket regulator. If not specified, heuristics based on the interface ' .
1214 806942d0 Stephen Beaver
					'bandwidth are used to determine the size.');
1215
1216 aef9d8fe Stephen Beaver
		$section->addInput(new Form_Input(
1217
			'interface',
1218
			null,
1219
			'hidden',
1220
			$this->GetInterface()
1221
		));
1222 806942d0 Stephen Beaver
1223 aef9d8fe Stephen Beaver
		$section->addInput(new Form_Input(
1224
			'name',
1225
			null,
1226
			'hidden',
1227
			$this->GetQname()
1228
		));
1229 806942d0 Stephen Beaver
1230 aef9d8fe Stephen Beaver
		$sform->add($section);
1231 806942d0 Stephen Beaver
1232 aef9d8fe Stephen Beaver
		return($sform);
1233 197bfe96 Ermal Luçi
	}
1234 061f78b1 Bill Marquette
1235 420b4538 Renato Botelho
	function update_altq_queue_data(&$data) {
1236 197bfe96 Ermal Luçi
		$this->ReadConfig($data);
1237 061f78b1 Bill Marquette
	}
1238 ce0117f7 Colin Fleming
1239 92125c97 Ermal Luçi
	/*
1240
	 * Should call on each of it queues and subqueues
1241
	 * the same function much like build_rules();
1242
	 */
1243 420b4538 Renato Botelho
	function wconfig() {
1244 92125c97 Ermal Luçi
		$cflink = &get_reference_to_me_in_config($this->GetLink());
1245 61e047a5 Phil Davis
		if (!is_array($cflink)) {
1246 92125c97 Ermal Luçi
			$cflink = array();
1247 61e047a5 Phil Davis
		}
1248 420b4538 Renato Botelho
		$cflink['interface'] = $this->GetInterface();
1249 92125c97 Ermal Luçi
		$cflink['name'] = $this->GetQname();
1250
		$cflink['scheduler'] = $this->GetScheduler();
1251
		$cflink['bandwidth'] = $this->GetBandwidth();
1252
		$cflink['bandwidthtype'] = $this->GetBwscale();
1253 f5881023 Ermal Lu?i
		$cflink['qlimit'] = trim($this->GetQlimit());
1254 61e047a5 Phil Davis
		if (empty($cflink['qlimit'])) {
1255 f5881023 Ermal Lu?i
			unset($cflink['qlimit']);
1256 61e047a5 Phil Davis
		}
1257 f5881023 Ermal Lu?i
		$cflink['tbrconfig'] = trim($this->GetTbrConfig());
1258 61e047a5 Phil Davis
		if (empty($cflink['tbrconfig'])) {
1259 f5881023 Ermal Lu?i
			unset($cflink['tbrconfig']);
1260 61e047a5 Phil Davis
		}
1261 92125c97 Ermal Luçi
		$cflink['enabled'] = $this->GetEnabled();
1262 61e047a5 Phil Davis
		if (empty($cflink['enabled'])) {
1263 f5881023 Ermal Lu?i
			unset($cflink['enabled']);
1264 61e047a5 Phil Davis
		}
1265 92125c97 Ermal Luçi
	}
1266 061f78b1 Bill Marquette
1267 197bfe96 Ermal Luçi
}
1268 061f78b1 Bill Marquette
1269 197bfe96 Ermal Luçi
class priq_queue {
1270 92125c97 Ermal Luçi
	var $qname;
1271 420b4538 Renato Botelho
	var $qinterface;
1272 92125c97 Ermal Luçi
	var $qlimit;
1273
	var $qpriority;
1274
	var $description;
1275
	var $isparent;
1276 197bfe96 Ermal Luçi
	var $qbandwidth;
1277
	var $qbandwidthtype;
1278 f5881023 Ermal Lu?i
	var $qdefault = "";
1279
	var $qrio = "";
1280
	var $qred = "";
1281 8edaa92c Ermal
	var $qcodel = "";
1282 f5881023 Ermal Lu?i
	var $qecn = "";
1283 197bfe96 Ermal Luçi
	var $qack;
1284 f5881023 Ermal Lu?i
	var $qenabled = "";
1285 197bfe96 Ermal Luçi
	var $qparent;
1286
	var $link;
1287 92125c97 Ermal Luçi
1288 70b139a3 Chris Buechler
	/* This is here to help with form building and building rules/lists */
1289 57c448d0 Ermal
	var $subqueues = array();
1290 92125c97 Ermal Luçi
1291 d6fa899d Phil Davis
	/* Accessor functions */
1292 92125c97 Ermal Luçi
	function SetLink($link) {
1293 f5881023 Ermal Lu?i
		$this->link = $link;
1294 92125c97 Ermal Luçi
	}
1295
	function GetLink() {
1296 f5881023 Ermal Lu?i
		return $this->link;
1297 92125c97 Ermal Luçi
	}
1298 197bfe96 Ermal Luçi
	function &GetParent() {
1299
		return $this->qparent;
1300
	}
1301
	function SetParent(&$parent) {
1302
		$this->qparent = &$parent;
1303
	}
1304 92125c97 Ermal Luçi
	function GetEnabled() {
1305 f5881023 Ermal Lu?i
		return $this->qenabled;
1306 92125c97 Ermal Luçi
	}
1307
	function SetEnabled($value) {
1308 f5881023 Ermal Lu?i
		$this->qenabled = $value;
1309 92125c97 Ermal Luçi
	}
1310 70b139a3 Chris Buechler
	function CanHaveChildren() {
1311 f5881023 Ermal Lu?i
		return false;
1312 92125c97 Ermal Luçi
	}
1313 197bfe96 Ermal Luçi
	function CanBeDeleted() {
1314 f5881023 Ermal Lu?i
		return true;
1315 92125c97 Ermal Luçi
	}
1316
	function GetQname() {
1317 f5881023 Ermal Lu?i
		return $this->qname;
1318 92125c97 Ermal Luçi
	}
1319
	function SetQname($name) {
1320 f5881023 Ermal Lu?i
		$this->qname = trim($name);
1321 92125c97 Ermal Luçi
	}
1322
	function GetBandwidth() {
1323 f5881023 Ermal Lu?i
		return $this->qbandwidth;
1324 92125c97 Ermal Luçi
	}
1325
	function SetBandwidth($bandwidth) {
1326 f5881023 Ermal Lu?i
		$this->qbandwidth = $bandwidth;
1327 92125c97 Ermal Luçi
	}
1328
	function GetInterface() {
1329 f5881023 Ermal Lu?i
		return $this->qinterface;
1330 92125c97 Ermal Luçi
	}
1331
	function SetInterface($name) {
1332 f5881023 Ermal Lu?i
		$this->qinterface = trim($name);
1333 92125c97 Ermal Luçi
	}
1334
	function GetQlimit() {
1335 f5881023 Ermal Lu?i
		return $this->qlimit;
1336 92125c97 Ermal Luçi
	}
1337
	function SetQlimit($limit) {
1338 f5881023 Ermal Lu?i
		$this->qlimit = $limit;
1339 92125c97 Ermal Luçi
	}
1340
	function GetQpriority() {
1341 6ddd28f7 Viktor G
		if (is_numeric($this->qpriority)) {
1342
			return $this->qpriority;
1343
		} else {
1344
			return '1';
1345
		}
1346 92125c97 Ermal Luçi
	}
1347
	function SetQpriority($priority) {
1348 f5881023 Ermal Lu?i
		$this->qpriority = $priority;
1349 92125c97 Ermal Luçi
	}
1350
	function GetDescription() {
1351 f5881023 Ermal Lu?i
		return $this->description;
1352 92125c97 Ermal Luçi
	}
1353
	function SetDescription($str) {
1354 f5881023 Ermal Lu?i
		$this->description = trim($str);
1355 92125c97 Ermal Luçi
	}
1356
	function GetFirstime() {
1357 f5881023 Ermal Lu?i
		return $this->firsttime;
1358 92125c97 Ermal Luçi
	}
1359
	function SetFirsttime($number) {
1360 f5881023 Ermal Lu?i
		$this->firsttime = $number;
1361 92125c97 Ermal Luçi
	}
1362 45eeb038 Luiz Otavio O Souza
	function CheckBandwidth($bw, $bwtype) {
1363
		$parent = $this->GetParent();
1364 fbbd7d2b Steve Beaver
1365
		// If the child queues have bandwidth specified in %, there is no point trying
1366
		// to compare the total to the parent's bandwidth, which is defined in Kb/S or Mb/S etc.
1367
		// ToDo: Add check for total % > 100
1368
		//		 If one child is in %, they must all be
1369
1370
		if ($bwtype != "%") {
1371
			$sum = $parent->GetTotalBw(($bw > 0) ? $this : NULL);
1372
1373
			if ($bw > 0) {
1374
				$sum += get_bandwidth($bw, $bwtype, $parent);
1375
			}
1376
1377
			if ($sum > get_queue_bandwidth($parent)) {
1378
				return 1;
1379
			}
1380
		}
1381 45eeb038 Luiz Otavio O Souza
1382
		foreach ($this->subqueues as $q) {
1383 fbbd7d2b Steve Beaver
			if ($q->CheckBandwidth(0, '')) {
1384 45eeb038 Luiz Otavio O Souza
				return 1;
1385 fbbd7d2b Steve Beaver
			}
1386 45eeb038 Luiz Otavio O Souza
		}
1387
1388
		return 0;
1389
	}
1390
	function GetTotalBw($qignore = NULL) {
1391 2638ddec Luiz Otavio O Souza
		$sum = 0;
1392
		foreach ($this->subqueues as $q) {
1393 45eeb038 Luiz Otavio O Souza
			if ($qignore != NULL && $qignore == $q)
1394
				continue;
1395
			$sum += get_bandwidth($q->GetBandwidth(), $q->GetBwscale(), $q->GetParent());
1396 2638ddec Luiz Otavio O Souza
		}
1397
1398
		return $sum;
1399
	}
1400 92125c97 Ermal Luçi
	function GetBwscale() {
1401 f5881023 Ermal Lu?i
		return $this->qbandwidthtype;
1402 92125c97 Ermal Luçi
	}
1403 9abbcb4b Viktor G
	function FormGetBwscale() {
1404
		if ($this->GetBwscale()) {
1405
			$bwscale = $this->GetBwscale();
1406
		} else {
1407
			$bwscale = 'Mb';
1408
		}
1409
		return $bwscale;
1410
	}
1411 92125c97 Ermal Luçi
	function SetBwscale($scale) {
1412 f5881023 Ermal Lu?i
		$this->qbandwidthtype = $scale;
1413 92125c97 Ermal Luçi
	}
1414 f61dc8e6 Ermal
	function GetDefaultQueuePresent() {
1415 61e047a5 Phil Davis
		if ($this->GetDefault()) {
1416 f61dc8e6 Ermal
			return true;
1417 61e047a5 Phil Davis
		}
1418 f61dc8e6 Ermal
		if (!empty($this->subqueues)) {
1419
			foreach ($this->subqueues as $q) {
1420 61e047a5 Phil Davis
				if ($q->GetDefault()) {
1421 f61dc8e6 Ermal
					return true;
1422 61e047a5 Phil Davis
				}
1423 f61dc8e6 Ermal
			}
1424
		}
1425
1426
		return false;
1427
	}
1428 197bfe96 Ermal Luçi
	function GetDefault() {
1429 f5881023 Ermal Lu?i
		return $this->qdefault;
1430 92125c97 Ermal Luçi
	}
1431
	function SetDefault($value = false) {
1432 f5881023 Ermal Lu?i
		$this->qdefault = $value;
1433 92125c97 Ermal Luçi
	}
1434 8edaa92c Ermal
	function GetCodel() {
1435
		return $this->codel;
1436
	}
1437
	function SetCodel($codel = false) {
1438
		$this->codel = $codel;
1439
	}
1440 197bfe96 Ermal Luçi
	function GetRed() {
1441 f5881023 Ermal Lu?i
		return $this->qred;
1442 92125c97 Ermal Luçi
	}
1443
	function SetRed($red = false) {
1444 f5881023 Ermal Lu?i
		$this->qred = $red;
1445 92125c97 Ermal Luçi
	}
1446 197bfe96 Ermal Luçi
	function GetRio() {
1447 f5881023 Ermal Lu?i
		return $this->qrio;
1448 92125c97 Ermal Luçi
	}
1449
	function SetRio($rio = false) {
1450 f5881023 Ermal Lu?i
		$this->qrio = $rio;
1451 92125c97 Ermal Luçi
	}
1452 f5881023 Ermal Lu?i
	function GetEcn() {
1453
		return $this->qecn;
1454 92125c97 Ermal Luçi
	}
1455
	function SetEcn($ecn = false) {
1456 f5881023 Ermal Lu?i
		$this->qecn = $ecn;
1457 92125c97 Ermal Luçi
	}
1458 197bfe96 Ermal Luçi
	function GetAck() {
1459 f5881023 Ermal Lu?i
		return $this->qack;
1460 92125c97 Ermal Luçi
	}
1461
	function SetAck($ack = false) {
1462 f5881023 Ermal Lu?i
		$this->qack = $ack;
1463 92125c97 Ermal Luçi
	}
1464 197bfe96 Ermal Luçi
1465 bfc94df0 Phil Davis
	function GetBwscaleText() {
1466
		switch ($this->qbandwidthtype) {
1467
			case "b":
1468
				$bwscaletext = "Bit/s";
1469
				break;
1470
			case "Kb":
1471
				$bwscaletext = "Kbit/s";
1472
				break;
1473
			case "Mb":
1474
				$bwscaletext = "Mbit/s";
1475
				break;
1476
			case "Gb":
1477
				$bwscaletext = "Gbit/s";
1478
				break;
1479
			default:
1480
				/* For others that do not need translating like % */
1481
				$bwscaletext = $this->qbandwidthtype;
1482
				break;
1483
		}
1484
		return $bwscaletext;
1485
	}
1486
1487 197bfe96 Ermal Luçi
	function build_javascript() {
1488
		$javascript = "<script type=\"text/javascript\">";
1489 ee02550a Michele Di Maria
		$javascript .= "//<![CDATA[\n";
1490 197bfe96 Ermal Luçi
		$javascript .= "function mySuspend() { \n";
1491 01890f6a Ermal
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null)\n";
1492 92125c97 Ermal Luçi
		$javascript .= "document.layers['shaperarea'].visibility = 'hidden';\n";
1493
		$javascript .= "else if (document.all)\n";
1494
		$javascript .= "document.all['shaperarea'].style.visibility = 'hidden';\n";
1495
		$javascript .= "}\n";
1496
1497
		$javascript .= "function myResume() {\n";
1498
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null)\n";
1499
		$javascript .= "document.layers['shaperarea'].visibility = 'visible';\n";
1500
		$javascript .= "else if (document.all)\n";
1501
		$javascript .= "document.all['shaperarea'].style.visibility = 'visible';\n";
1502
		$javascript .= "}\n";
1503 0fa05f45 Colin Fleming
		$javascript .= "//]]>";
1504 92125c97 Ermal Luçi
		$javascript .= "</script>";
1505 ce0117f7 Colin Fleming
1506 197bfe96 Ermal Luçi
		return $javascript;
1507
	}
1508 ce0117f7 Colin Fleming
1509 6f627d41 Ermal Luçi
	function &add_queue($interface, &$qname, &$path, &$input_errors) { return; }
1510
1511 420b4538 Renato Botelho
	/*
1512
	 * Currently this will not be called unless we decide to clone a whole
1513 197bfe96 Ermal Luçi
	 * queue tree on the 'By Queues' view or support drag&drop on the tree/list
1514
	 */
1515 420b4538 Renato Botelho
	function copy_queue($interface, &$cflink) {
1516
1517
		$cflink['name'] = $this->GetQname();
1518
		$cflink['interface'] = $interface;
1519
		$cflink['qlimit'] = $this->GetQlimit();
1520
		$cflink['priority'] = $this->GetQpriority();
1521
		$cflink['description'] = $this->GetDescription();
1522
		$cflink['enabled'] = $this->GetEnabled();
1523
		$cflink['default'] = $this->GetDefault();
1524
		$cflink['red'] = $this->GetRed();
1525
		$cflink['codel'] = $this->GetCodel();
1526
		$cflink['rio'] = $this->GetRio();
1527
		$cflink['ecn'] = $this->GetEcn();
1528
1529
		if (is_array($this->subqueues)) {
1530
			$cflinkp['queue'] = array();
1531
			foreach ($this->subqueues as $q) {
1532
				$cflink['queue'][$q->GetQname()] = array();
1533
				$q->copy_queue($interface, $cflink['queue'][$q->GetQname()]);
1534 a843b04f Ermal Luçi
			}
1535 420b4538 Renato Botelho
		}
1536
	}
1537 197bfe96 Ermal Luçi
1538
	function clean_queue($sched) {
1539 92125c97 Ermal Luçi
		clean_child_queues($sched, $this->GetLink());
1540
		if (is_array($this->subqueues)) {
1541 61e047a5 Phil Davis
			foreach ($this->subqueues as $q) {
1542 f5881023 Ermal Lu?i
				$q->clean_queue($sched);
1543 61e047a5 Phil Davis
			}
1544 92125c97 Ermal Luçi
		}
1545 f5881023 Ermal Lu?i
	}
1546 197bfe96 Ermal Luçi
1547 420b4538 Renato Botelho
	function &get_queue_list(&$qlist) {
1548 ce0117f7 Colin Fleming
1549 f5881023 Ermal Lu?i
		$qlist[$this->GetQname()] = & $this;
1550
		if (is_array($this->subqueues)) {
1551 61e047a5 Phil Davis
			foreach ($this->subqueues as $queue) {
1552 f5881023 Ermal Lu?i
				$queue->get_queue_list($qlist);
1553 61e047a5 Phil Davis
			}
1554 f5881023 Ermal Lu?i
		}
1555
	}
1556 fe93b17b Ermal Luçi
1557 197bfe96 Ermal Luçi
	function delete_queue() {
1558 92125c97 Ermal Luçi
		unref_on_altq_queue_list($this->GetQname());
1559
		cleanup_queue_from_rules($this->GetQname());
1560
		unset_object_by_reference($this->GetLink());
1561
	}
1562 ce0117f7 Colin Fleming
1563 b0262cb2 Ermal Luçi
	function delete_all() {
1564 420b4538 Renato Botelho
		if (count($this->subqueues)) {
1565
			foreach ($this->subqueues as $q) {
1566
				$q->delete_all();
1567
				unset_object_by_reference($q->GetLink());
1568
				unset($q);
1569
			}
1570
			unset($this->subqueues);
1571
		}
1572
	}
1573
1574
	function &find_queue($interface, $qname) {
1575 61e047a5 Phil Davis
		if ($qname == $this->GetQname()) {
1576 420b4538 Renato Botelho
			return $this;
1577 61e047a5 Phil Davis
		}
1578 197bfe96 Ermal Luçi
	}
1579 ce0117f7 Colin Fleming
1580 62150088 Ermal Lu?i
	function find_parentqueue($interface, $qname) { return; }
1581 ce0117f7 Colin Fleming
1582 92125c97 Ermal Luçi
	function validate_input($data, &$input_errors) {
1583 a330a2da Viktor G
		global $altq_list_queues;
1584 ce0117f7 Colin Fleming
1585 2c072899 jim-p
		$reqdfields[] = "name";
1586 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Name");
1587 40de74f5 Ermal Luçi
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
1588 a330a2da Viktor G
		$parent = $altq_list_queues[$this->GetInterface()];
1589 197bfe96 Ermal Luçi
1590 b0f0993d Viktor G
		if ($data['bandwidth'] && !is_numeric($data['bandwidth'])) {
1591 e8c516a0 Phil Davis
			$input_errors[] = gettext("Bandwidth must be an integer.");
1592 61e047a5 Phil Davis
		}
1593
		if ($data['bandwidth'] < 0) {
1594 e8c516a0 Phil Davis
			$input_errors[] = gettext("Bandwidth cannot be negative.");
1595 61e047a5 Phil Davis
		}
1596 45eeb038 Luiz Otavio O Souza
		if ($data['bandwidthtype'] == "%") {
1597 b0f0993d Viktor G
			if (($data['bandwidth'] > 100) || ($data['bandwidth'] < 0)) {
1598 45eeb038 Luiz Otavio O Souza
				$input_errors[] = gettext("Bandwidth in percentage should be between 1 and 100.");
1599
			}
1600
		}
1601
		if ($this->CheckBandwidth($data['bandwidth'], $data['bandwidthtype']))
1602
			$input_errors[] = "The sum of child bandwidth is higher than parent.";
1603 fbbd7d2b Steve Beaver
1604 bf4c4d12 Viktor G
		if ($parent) {
1605
			if (($parent->GetScheduler() == 'PRIQ') && (!is_numeric($data['priority']) ||
1606
			    ($data['priority'] < 0) || ($data['priority'] > 15))) {
1607
				$input_errors[] = gettext("The priority must be an integer between 0 and 15.");
1608
			} elseif (in_array($parent->GetScheduler(), array('FAIRQ','CBQ')) && (!is_numeric($data['priority']) ||
1609
			    ($data['priority'] < 0) || ($data['priority'] > 7))) {
1610
				$input_errors[] = gettext("The priority must be an integer between 0 and 7.");
1611
			}
1612
			if (is_array($parent->queues)) {
1613
				foreach ($parent->queues as $q) {
1614
					if (($data['newname'] == $q->GetQname()) && ($data['name'] != $data['newname'])) { 
1615
						$input_errors[] = gettext("A queue with the same name already exists.");
1616
					}
1617
					if (in_array($parent->GetScheduler(), array('FAIRQ','PRIQ')) &&
1618
					    ($data['priority'] == $q->GetQpriority()) && ($data['name'] != $q->GetQname())) { 
1619
						$input_errors[] = sprintf(gettext("The priority %d is already used by queue %s."),
1620
								$data['priority'], $q->GetQname());
1621
					}
1622
				}
1623
			}
1624 92125c97 Ermal Luçi
		}
1625 6ddd28f7 Viktor G
1626 61e047a5 Phil Davis
		if ($data['qlimit'] && (!is_numeric($data['qlimit']))) {
1627 dbaf21d4 Renato Botelho
				$input_errors[] = gettext("Queue limit must be an integer");
1628 61e047a5 Phil Davis
		}
1629
		if ($data['qlimit'] < 0) {
1630 dbaf21d4 Renato Botelho
				$input_errors[] = gettext("Queue limit must be positive");
1631 61e047a5 Phil Davis
		}
1632
		if (!empty($data['newname']) && !preg_match("/^[a-zA-Z0-9_-]*$/", $data['newname'])) {
1633 420b4538 Renato Botelho
			$input_errors[] = gettext("Queue names must be alphanumeric and _ or - only.");
1634 61e047a5 Phil Davis
		}
1635
		if (!empty($data['name']) && !preg_match("/^[a-zA-Z0-9_-]*$/", $data['name'])) {
1636 420b4538 Renato Botelho
			$input_errors[] = gettext("Queue names must be alphanumeric and _ or - only.");
1637 61e047a5 Phil Davis
		}
1638 f8dca5a3 Renato Botelho
		$default = $this->GetDefault();
1639 61e047a5 Phil Davis
		if (!empty($data['default']) && altq_get_default_queue($data['interface']) && empty($default)) {
1640 f61dc8e6 Ermal
			$input_errors[] = gettext("Only one default queue per interface is allowed.");
1641 61e047a5 Phil Davis
		}
1642 061f78b1 Bill Marquette
	}
1643
1644 92125c97 Ermal Luçi
	function ReadConfig(&$q) {
1645 b0f0993d Viktor G
		if (!empty($q['name']) && !empty($q['newname']) && ($q['name'] != $q['newname'])) {
1646 30ef6f8d Ermal
			$this->SetQname($q['newname']);
1647 402012d9 Viktor G
			rename_queue_in_rules($q['name'], $q['newname']);
1648 30ef6f8d Ermal
		} else if (!empty($q['newname'])) {
1649
			$this->SetQname($q['newname']);
1650 b0f0993d Viktor G
		} elseif (isset($q['name'])) {
1651 30ef6f8d Ermal
			$this->SetQname($q['name']);
1652 61e047a5 Phil Davis
		}
1653
		if (isset($q['interface'])) {
1654 f61dc8e6 Ermal
			$this->SetInterface($q['interface']);
1655 61e047a5 Phil Davis
		}
1656 0b13e3f9 Ermal
		$this->SetBandwidth($q['bandwidth']);
1657 b0f0993d Viktor G
		if (!empty($q['bandwidthtype'])) {
1658 0b13e3f9 Ermal
			$this->SetBwscale($q['bandwidthtype']);
1659 61e047a5 Phil Davis
		}
1660
		if (!empty($q['qlimit'])) {
1661 f5881023 Ermal Lu?i
			$this->SetQlimit($q['qlimit']);
1662 61e047a5 Phil Davis
		} else {
1663 ea25d26d Ermal Lu?i
			$this->SetQlimit(""); // Default
1664 61e047a5 Phil Davis
		}
1665 41799195 PiBa-NL
		if (is_numeric($q['priority'])) {
1666 f5881023 Ermal Lu?i
			$this->SetQPriority($q['priority']);
1667 61e047a5 Phil Davis
		} else {
1668 ea25d26d Ermal Lu?i
			$this->SetQpriority("");
1669 61e047a5 Phil Davis
		}
1670
		if (!empty($q['description'])) {
1671 f5881023 Ermal Lu?i
			$this->SetDescription($q['description']);
1672 61e047a5 Phil Davis
		} else {
1673 da0ce7ee Chris Buechler
			$this->SetDescription("");
1674 61e047a5 Phil Davis
		}
1675
		if (!empty($q['red'])) {
1676 f5881023 Ermal Lu?i
			$this->SetRed($q['red']);
1677 61e047a5 Phil Davis
		} else {
1678 ea25d26d Ermal Lu?i
			$this->SetRed();
1679 61e047a5 Phil Davis
		}
1680
		if (!empty($q['codel'])) {
1681 8edaa92c Ermal
			$this->SetCodel($q['codel']);
1682 61e047a5 Phil Davis
		} else {
1683 8edaa92c Ermal
			$this->SetCodel();
1684 61e047a5 Phil Davis
		}
1685
		if (!empty($q['rio'])) {
1686 f5881023 Ermal Lu?i
			$this->SetRio($q['rio']);
1687 61e047a5 Phil Davis
		} else {
1688 ea25d26d Ermal Lu?i
			$this->SetRio();
1689 61e047a5 Phil Davis
		}
1690
		if (!empty($q['ecn'])) {
1691 f5881023 Ermal Lu?i
			$this->SetEcn($q['ecn']);
1692 61e047a5 Phil Davis
		} else {
1693 ea25d26d Ermal Lu?i
			$this->SetEcn();
1694 61e047a5 Phil Davis
		}
1695
		if (!empty($q['default'])) {
1696 f5881023 Ermal Lu?i
			$this->SetDefault($q['default']);
1697 61e047a5 Phil Davis
		} else {
1698 ea25d26d Ermal Lu?i
			$this->SetDefault();
1699 61e047a5 Phil Davis
		}
1700
		if (!empty($q['enabled'])) {
1701 f5881023 Ermal Lu?i
			$this->SetEnabled($q['enabled']);
1702 61e047a5 Phil Davis
		} else {
1703 ea25d26d Ermal Lu?i
			$this->SetEnabled("");
1704 61e047a5 Phil Davis
		}
1705 f5881023 Ermal Lu?i
	}
1706 197bfe96 Ermal Luçi
1707
	function build_tree() {
1708 1072b933 jim-p
		$tree = " <li><a href=\"firewall_shaper.php?interface=". $this->GetInterface()."&amp;queue=". htmlspecialchars($this->GetQname())."&amp;action=show";
1709 f5881023 Ermal Lu?i
		$tree .= "\" ";
1710
		$tmpvalue = $this->GetDefault();
1711 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
1712 f5881023 Ermal Lu?i
			$tree .= " class=\"navlnk\"";
1713 61e047a5 Phil Davis
		}
1714 1072b933 jim-p
		$tree .= " >" . htmlspecialchars($this->GetQname()) . "</a>";
1715 420b4538 Renato Botelho
		/*
1716 f5881023 Ermal Lu?i
		 * Not needed here!
1717
		 * if (is_array($queues) {
1718
		 *	  $tree .= "<ul>";
1719 420b4538 Renato Botelho
		 *	  foreach ($q as $queues)
1720 f5881023 Ermal Lu?i
		 *		  $tree .= $queues['$q->GetName()']->build_tree();
1721 420b4538 Renato Botelho
		 *	  endforeach
1722 f5881023 Ermal Lu?i
		 *	  $tree .= "</ul>";
1723
		 * }
1724 92125c97 Ermal Luçi
		 */
1725 f5881023 Ermal Lu?i
1726 420b4538 Renato Botelho
		$tree .= "</li>";
1727 f5881023 Ermal Lu?i
1728
		return $tree;
1729
	}
1730 ce0117f7 Colin Fleming
1731 f5881023 Ermal Lu?i
	/* Should return something like:
1732
	 * queue $qname on $qinterface bandwidth ....
1733
	 */
1734 9d0b0635 Ermal
	function build_rules(&$default = false) {
1735 f5881023 Ermal Lu?i
		$pfq_rule = " queue ". $this->qname;
1736 61e047a5 Phil Davis
		if ($this->GetInterface()) {
1737 f5881023 Ermal Lu?i
			$pfq_rule .= " on ".get_real_interface($this->GetInterface());
1738 61e047a5 Phil Davis
		}
1739 f5881023 Ermal Lu?i
		$tmpvalue = $this->GetQpriority();
1740 41799195 PiBa-NL
		if (is_numeric($tmpvalue)) {
1741 f5881023 Ermal Lu?i
			$pfq_rule .= " priority ".$this->GetQpriority();
1742 61e047a5 Phil Davis
		}
1743 f5881023 Ermal Lu?i
		$tmpvalue = $this->GetQlimit();
1744 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
1745 f5881023 Ermal Lu?i
			$pfq_rule .= " qlimit " . $this->GetQlimit();
1746 61e047a5 Phil Davis
		}
1747 8edaa92c Ermal
		if ($this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetDefault() || $this->GetCodel()) {
1748 f5881023 Ermal Lu?i
			$pfq_rule .= " priq ( ";
1749
			$tmpvalue = $this->GetRed();
1750
			if (!empty($tmpvalue)) {
1751
				$comma = 1;
1752
				$pfq_rule .= " red ";
1753
			}
1754
			$tmpvalue = $this->GetRio();
1755
			if (!empty($tmpvalue)) {
1756 61e047a5 Phil Davis
				if ($comma) {
1757 f5881023 Ermal Lu?i
					$pfq_rule .= " ,";
1758 61e047a5 Phil Davis
				}
1759 f5881023 Ermal Lu?i
				$comma = 1;
1760
				$pfq_rule .= " rio ";
1761
			}
1762
			$tmpvalue = $this->GetEcn();
1763
			if (!empty($tmpvalue)) {
1764 61e047a5 Phil Davis
				if ($comma) {
1765 f5881023 Ermal Lu?i
					$pfq_rule .= " ,";
1766 61e047a5 Phil Davis
				}
1767 f5881023 Ermal Lu?i
				$comma = 1;
1768
				$pfq_rule .= " ecn ";
1769
			}
1770 8edaa92c Ermal
			$tmpvalue = $this->GetCodel();
1771
			if (!empty($tmpvalue)) {
1772 61e047a5 Phil Davis
				if ($comma) {
1773 8edaa92c Ermal
					$pfq_rule .= " ,";
1774 61e047a5 Phil Davis
				}
1775 8edaa92c Ermal
				$comma = 1;
1776
				$pfq_rule .= " codel ";
1777
			}
1778 f5881023 Ermal Lu?i
			$tmpvalue = $this->GetDefault();
1779
			if (!empty($tmpvalue)) {
1780 61e047a5 Phil Davis
				if ($comma) {
1781 f5881023 Ermal Lu?i
					$pfq_rule .= " ,";
1782 61e047a5 Phil Davis
				}
1783 f5881023 Ermal Lu?i
				$pfq_rule .= " default ";
1784 ef8fca71 Ermal
				$default = true;
1785 f5881023 Ermal Lu?i
			}
1786
			$pfq_rule .= " ) ";
1787 92125c97 Ermal Luçi
		}
1788
1789 f5881023 Ermal Lu?i
		$pfq_rule .= " \n";
1790
1791
		return $pfq_rule;
1792
	}
1793
1794
	/*
1795
	 * To return the html form to show to user
1796
	 * for getting the parameters.
1797
	 * Should do even for first time when the
1798
	 * object is created and later when we may
1799 aef9d8fe Stephen Beaver
	 * need to update it. (2)
1800 f5881023 Ermal Lu?i
	 */
1801 806942d0 Stephen Beaver
1802 f5881023 Ermal Lu?i
	function build_form() {
1803 806942d0 Stephen Beaver
1804 27d6a45b jim-p
		$sform = new Form();
1805 5605a0c4 Stephen Beaver
1806
		$sform->setAction("firewall_shaper.php");
1807 806942d0 Stephen Beaver
1808 3feefc07 Stephen Beaver
		$section = new Form_Section("");
1809 806942d0 Stephen Beaver
1810 aef9d8fe Stephen Beaver
		$section->addInput(new Form_Checkbox(
1811
			'enabled',
1812
			'Enable/Disable',
1813
			'Enable/disable discipline and its children',
1814
			($this->GetEnabled() == "on"),
1815
			'on'
1816
		));
1817 806942d0 Stephen Beaver
1818 3feefc07 Stephen Beaver
		$section->addInput(new Form_Input(
1819 5605a0c4 Stephen Beaver
			'newname',
1820 40dcb4b6 Phil Davis
			'*Name',
1821 3feefc07 Stephen Beaver
			'text',
1822 aef9d8fe Stephen Beaver
			$this->GetQname()
1823
		))->setHelp('Enter the name of the queue here. Do not use spaces and limit the size to 15 characters.');
1824 806942d0 Stephen Beaver
1825 5605a0c4 Stephen Beaver
		$section->addInput(new Form_Input(
1826
			'name',
1827
			null,
1828
			'hidden',
1829
			$this->GetQname()
1830
		));
1831
1832 41799195 PiBa-NL
		if (!is_a($this, "hfsc_queue")) {
1833
			$section->addInput(new Form_Input(
1834
				'priority',
1835
				'Priority',
1836
				'number',
1837
				$this->GetQpriority(),
1838
				['min' => '0', 'max'=> '']
1839
			))->setHelp('For cbq and fairq the range is 0 to 7. The default is 1. For priq the range is 0 to 15, queues with a higher priority are preferred in the case of overload.');
1840
		}
1841 aef9d8fe Stephen Beaver
1842
		$section->addInput(new Form_Input(
1843
			'qlimit',
1844
			'Queue Limit',
1845
			'number',
1846
			$this->GetQlimit()
1847
		))->setHelp('Queue limit in packets.');
1848 806942d0 Stephen Beaver
1849 aef9d8fe Stephen Beaver
		$group = new Form_Group('Scheduler options');
1850 806942d0 Stephen Beaver
1851 bc788561 Ermal
		if (empty($this->subqueues)) {
1852 aef9d8fe Stephen Beaver
			$group->add(new Form_Checkbox(
1853
				'default',
1854
				null,
1855
				null,
1856 5605a0c4 Stephen Beaver
				$this->GetDefault(),
1857
				'default'
1858 806942d0 Stephen Beaver
			))->setHelp('Default Queue');
1859 aef9d8fe Stephen Beaver
		}
1860 806942d0 Stephen Beaver
1861 aef9d8fe Stephen Beaver
		$group->add(new Form_Checkbox(
1862
			'red',
1863
			null,
1864
			null,
1865
			!empty($this->GetRed())
1866 50299413 jim-p
		))->setHelp('%1$sRandom Early Detection%2$s', '<a target="_new" href="https://docs.netgate.com/pfsense/en/latest/trafficshaper/advanced.html#editing-shaper-queues">', '</a>');
1867 806942d0 Stephen Beaver
1868 aef9d8fe Stephen Beaver
		$group->add(new Form_Checkbox(
1869
			'rio',
1870
			null,
1871
			null,
1872
			!empty($this->GetRio())
1873 50299413 jim-p
		))->setHelp('%1$sRandom Early Detection In and Out%2$s', '<a target="_new" href="https://docs.netgate.com/pfsense/en/latest/trafficshaper/advanced.html#editing-shaper-queues">', '</a>');
1874 806942d0 Stephen Beaver
1875 aef9d8fe Stephen Beaver
		$group->add(new Form_Checkbox(
1876
			'ecn',
1877
			null,
1878
			null,
1879
			!empty($this->GetEcn())
1880 50299413 jim-p
		))->setHelp('%1$sExplicit Congestion Notification%2$s', '<a target="_new" href="https://docs.netgate.com/pfsense/en/latest/trafficshaper/advanced.html#editing-shaper-queues">', '</a>');
1881 806942d0 Stephen Beaver
1882 aef9d8fe Stephen Beaver
		$group->add(new Form_Checkbox(
1883
			'codel',
1884
			null,
1885
			null,
1886
			!empty($this->GetCodel())
1887 50299413 jim-p
		))->setHelp('%1$sCodel Active Queue%2$s', '<a target="_new" href="https://docs.netgate.com/pfsense/en/latest/trafficshaper/altq-scheduler-types.html#codel-active-queue-management">', '</a>');
1888 aef9d8fe Stephen Beaver
1889
		$group->setHelp('Select options for this queue');
1890 806942d0 Stephen Beaver
1891
		$section->add($group);
1892
1893 aef9d8fe Stephen Beaver
		$section->addInput(new Form_Input(
1894
			'description',
1895
			'Description',
1896
			'text',
1897
			$this->GetDescription()
1898
		));
1899 806942d0 Stephen Beaver
1900 5605a0c4 Stephen Beaver
		$sform->add($section);
1901
1902
		$sform->addGlobal(new Form_Input(
1903 aef9d8fe Stephen Beaver
			'interface',
1904
			null,
1905
			'hidden',
1906
			$this->GetInterface()
1907 806942d0 Stephen Beaver
		));
1908
1909 5605a0c4 Stephen Beaver
		$sform->addGlobal(new Form_Input(
1910
			'name',
1911
			null,
1912
			'hidden',
1913
			$this->GetQname()
1914
		));
1915 806942d0 Stephen Beaver
1916 aef9d8fe Stephen Beaver
		return($sform);
1917 806942d0 Stephen Beaver
	}
1918 197bfe96 Ermal Luçi
1919
	function build_shortform() {
1920 61e047a5 Phil Davis
		/* XXX: Hacks in sight. Mostly layer violations!  */
1921 197bfe96 Ermal Luçi
		global $g, $altq_list_queues;
1922 d34ade52 Michele Di Maria
		global $shaperIFlist;
1923 ce0117f7 Colin Fleming
1924 197bfe96 Ermal Luçi
		$altq =& $altq_list_queues[$this->GetInterface()];
1925 d17c4ee9 Stephen Beaver
1926 61e047a5 Phil Davis
		if ($altq) {
1927 b28e1512 Stephen Beaver
			$scheduler = $altq->GetScheduler();
1928
		}
1929 d17c4ee9 Stephen Beaver
1930 b28e1512 Stephen Beaver
		$form = '<dl class="dl-horizontal">';
1931
		$form .= '	<dt>';
1932
		$form .= '		<a href="firewall_shaper.php?interface=' . $this->GetInterface() . '&amp;queue=' . $this->GetQname() . '&amp;action=show">' . $shaperIFlist[$this->GetInterface()] . '</a>';
1933
		$form .= '	</dt>';
1934
		$form .= '	<dd>';
1935 d17c4ee9 Stephen Beaver
		$form .=		$scheduler;
1936 b28e1512 Stephen Beaver
		$form .= '	</dd>';
1937 d17c4ee9 Stephen Beaver
1938 b28e1512 Stephen Beaver
		$form .= '	<dt>';
1939 d17c4ee9 Stephen Beaver
		$form .=		'Bandwidth';
1940 b28e1512 Stephen Beaver
		$form .= '	</dt>';
1941
		$form .= '	<dd>';
1942 bfc94df0 Phil Davis
		$form .=		$this->GetBandwidth() . '&nbsp;' . $this->GetBwscaleText();
1943 b28e1512 Stephen Beaver
		$form .= '	</dd>';
1944 d17c4ee9 Stephen Beaver
1945 f5881023 Ermal Lu?i
		$tmpvalue = $this->GetQpriority();
1946 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
1947 d17c4ee9 Stephen Beaver
			$form .= '	<dt>';
1948
			$form .=		'Priority';
1949 b28e1512 Stephen Beaver
			$form .= '	<dt>';
1950
			$form .= '	<dd>';
1951 d17c4ee9 Stephen Beaver
			$form .=		'On';
1952 b28e1512 Stephen Beaver
			$form .= '	</dd>';
1953
		}
1954 d17c4ee9 Stephen Beaver
1955 f5881023 Ermal Lu?i
		$tmpvalue = $this->GetDefault();
1956 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
1957 d17c4ee9 Stephen Beaver
			$form .= '	<dt>';
1958
			$form .=		'Default';
1959 b28e1512 Stephen Beaver
			$form .= '	<dt>';
1960
			$form .= '	<dd>';
1961 d17c4ee9 Stephen Beaver
			$form .=		'On';
1962 b28e1512 Stephen Beaver
			$form .= '	</dd>';
1963
		}
1964 d17c4ee9 Stephen Beaver
1965
			$form .= '	<dt>';
1966 b28e1512 Stephen Beaver
			$form .= 'Delete';
1967
			$form .= '	<dt>';
1968
			$form .= '	<dd>';
1969
1970
			$form .= '<a class="btn btn-danger btn-xs" href="firewall_shaper_queues.php?interface=';
1971
			$form .= $this->GetInterface() . '&amp;queue=';
1972
			$form .= $this->GetQname() . '&amp;action=delete">';
1973 27d6a45b jim-p
			$form .= '<i class="fa fa-trash icon-embed-btn"></i>';
1974
			$form .= gettext("Delete Queue from this Interface") . '</a>';
1975 b28e1512 Stephen Beaver
1976 d17c4ee9 Stephen Beaver
			$form .= '	</dd>';
1977
1978
			$form .= '</dl>';
1979 ce0117f7 Colin Fleming
1980 197bfe96 Ermal Luçi
		return $form;
1981 061f78b1 Bill Marquette
1982 197bfe96 Ermal Luçi
	}
1983 061f78b1 Bill Marquette
1984 61e047a5 Phil Davis
	function update_altq_queue_data(&$q) {
1985 197bfe96 Ermal Luçi
		$this->ReadConfig($q);
1986
	}
1987 061f78b1 Bill Marquette
1988 f5881023 Ermal Lu?i
	function wconfig() {
1989
		$cflink =& get_reference_to_me_in_config($this->GetLink());
1990 61e047a5 Phil Davis
		if (!is_array($cflink)) {
1991 197bfe96 Ermal Luçi
			$cflink = array();
1992 61e047a5 Phil Davis
		}
1993 197bfe96 Ermal Luçi
		$cflink['name'] = $this->GetQname();
1994 f5881023 Ermal Lu?i
		$cflink['interface'] = $this->GetInterface();
1995
		$cflink['qlimit'] = trim($this->GetQlimit());
1996 61e047a5 Phil Davis
		if (empty($cflink['qlimit'])) {
1997 f5881023 Ermal Lu?i
			unset($cflink['qlimit']);
1998 61e047a5 Phil Davis
		}
1999 f5881023 Ermal Lu?i
		$cflink['priority'] = trim($this->GetQpriority());
2000 41799195 PiBa-NL
		if (!is_numeric($cflink['priority'])) {
2001 f5881023 Ermal Lu?i
			unset($cflink['priority']);
2002 61e047a5 Phil Davis
		}
2003 f5881023 Ermal Lu?i
		$cflink['description'] = trim($this->GetDescription());
2004 61e047a5 Phil Davis
		if (empty($cflink['description'])) {
2005 f5881023 Ermal Lu?i
			unset($cflink['description']);
2006 61e047a5 Phil Davis
		}
2007 f5881023 Ermal Lu?i
		$cflink['enabled'] = trim($this->GetEnabled());
2008 61e047a5 Phil Davis
		if (empty($cflink['enabled'])) {
2009 f5881023 Ermal Lu?i
			unset($cflink['enabled']);
2010 61e047a5 Phil Davis
		}
2011 f5881023 Ermal Lu?i
		$cflink['default'] = trim($this->GetDefault());
2012 61e047a5 Phil Davis
		if (empty($cflink['default'])) {
2013 f5881023 Ermal Lu?i
			unset($cflink['default']);
2014 61e047a5 Phil Davis
		}
2015 f5881023 Ermal Lu?i
		$cflink['red'] = trim($this->GetRed());
2016 61e047a5 Phil Davis
		if (empty($cflink['red'])) {
2017 f5881023 Ermal Lu?i
			unset($cflink['red']);
2018 61e047a5 Phil Davis
		}
2019 8edaa92c Ermal
		$cflink['codel'] = trim($this->GetCodel());
2020 61e047a5 Phil Davis
		if (empty($cflink['codel'])) {
2021 8edaa92c Ermal
			unset($cflink['codel']);
2022 61e047a5 Phil Davis
		}
2023 f5881023 Ermal Lu?i
		$cflink['rio'] = trim($this->GetRio());
2024 61e047a5 Phil Davis
		if (empty($cflink['rio'])) {
2025 f5881023 Ermal Lu?i
			unset($cflink['rio']);
2026 61e047a5 Phil Davis
		}
2027 f5881023 Ermal Lu?i
		$cflink['ecn'] = trim($this->GetEcn());
2028 61e047a5 Phil Davis
		if (empty($cflink['ecn'])) {
2029 f5881023 Ermal Lu?i
			unset($cflink['ecn']);
2030 61e047a5 Phil Davis
		}
2031 061f78b1 Bill Marquette
	}
2032
}
2033
2034 197bfe96 Ermal Luçi
class hfsc_queue extends priq_queue {
2035 f5881023 Ermal Lu?i
	/* realtime */
2036 197bfe96 Ermal Luçi
	var $realtime;
2037 f5881023 Ermal Lu?i
	var $r_m1;
2038
	var $r_d;
2039
	var $r_m2;
2040
	/* linkshare */
2041 197bfe96 Ermal Luçi
	var $linkshare;
2042 f5881023 Ermal Lu?i
	var $l_m1;
2043
	var $l_d;
2044
	var $l_m2;
2045
	/* upperlimit */
2046 197bfe96 Ermal Luçi
	var $upperlimit;
2047 f5881023 Ermal Lu?i
	var $u_m1;
2048
	var $u_d;
2049
	var $u_m2;
2050 197bfe96 Ermal Luçi
2051 f5881023 Ermal Lu?i
	/*
2052
	 * HFSC can have nested queues.
2053
	 */
2054 70b139a3 Chris Buechler
	function CanHaveChildren() {
2055 f5881023 Ermal Lu?i
		return true;
2056
	}
2057 197bfe96 Ermal Luçi
	function GetRealtime() {
2058 420b4538 Renato Botelho
		return $this->realtime;
2059 f5881023 Ermal Lu?i
	}
2060
	function GetR_m1() {
2061
		return $this->r_m1;
2062
	}
2063
	function GetR_d() {
2064
		return $this->r_d;
2065
	}
2066
	function GetR_m2() {
2067
		return $this->r_m2;
2068
	}
2069
	function SetRealtime() {
2070
		$this->realtime = "on";
2071
	}
2072
	function DisableRealtime() {
2073
		$this->realtime = "";
2074
	}
2075
	function SetR_m1($value) {
2076
		$this->r_m1 = $value;
2077
	}
2078
	function SetR_d($value) {
2079
		$this->r_d = $value;
2080
	}
2081
	function SetR_m2($value) {
2082
		$this->r_m2 = $value;
2083
	}
2084
	function GetLinkshare() {
2085
		return $this->linkshare;
2086
	}
2087
	function DisableLinkshare() {
2088
		$this->linkshare = "";
2089
	}
2090
	function GetL_m1() {
2091
		return $this->l_m1;
2092
	}
2093
	function GetL_d() {
2094
		return $this->l_d;
2095
	}
2096
	function GetL_m2() {
2097
		return $this->l_m2;
2098
	}
2099
	function SetLinkshare() {
2100
		$this->linkshare = "on";
2101
	}
2102
	function SetL_m1($value) {
2103
		$this->l_m1 = $value;
2104
	}
2105
	function SetL_d($value) {
2106
		$this->l_d = $value;
2107
	}
2108
	function SetL_m2($value) {
2109
		$this->l_m2 = $value;
2110
	}
2111
	function GetUpperlimit() {
2112
		return $this->upperlimit;
2113
	}
2114
	function GetU_m1() {
2115
		return $this->u_m1;
2116
	}
2117
	function GetU_d() {
2118
		return $this->u_d;
2119
	}
2120
	function GetU_m2() {
2121
		return $this->u_m2;
2122
	}
2123
	function SetUpperlimit() {
2124
		$this->upperlimit = "on";
2125
	}
2126
	function DisableUpperlimit() {
2127
		$this->upperlimit = "";
2128
	}
2129
	function SetU_m1($value) {
2130
		$this->u_m1 = $value;
2131
	}
2132
	function SetU_d($value) {
2133
		$this->u_d = $value;
2134
	}
2135
	function SetU_m2($value) {
2136
		$this->u_m2 = $value;
2137
	}
2138
2139
	function &add_queue($interface, &$qname, &$path, &$input_errors) {
2140
2141 61e047a5 Phil Davis
		if (!is_array($this->subqueues)) {
2142 f5881023 Ermal Lu?i
			$this->subqueues = array();
2143 61e047a5 Phil Davis
		}
2144 5c4fcabc Renato Botelho
		$__tmp_q = new hfsc_queue(); $q =& $__tmp_q;
2145 f5881023 Ermal Lu?i
		$q->SetInterface($this->GetInterface());
2146 ea51e9f8 Renato Botelho
		$q->SetParent($this);
2147 f5881023 Ermal Lu?i
		$q->ReadConfig($qname);
2148
		$q->validate_input($qname, $input_errors);
2149 197bfe96 Ermal Luçi
2150 f5881023 Ermal Lu?i
		$q->SetEnabled("on");
2151
		$q->SetLink($path);
2152
2153
		$this->subqueues[$q->GetQname()] =& $q; //new hfsc_queue()
2154
		ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
2155
		if (is_array($qname['queue'])) {
2156
			foreach ($qname['queue'] as $key1 => $que) {
2157
				array_push($path, $key1);
2158 ea51e9f8 Renato Botelho
				$q->add_queue($q->GetInterface(), $que, $path, $input_errors);
2159 f5881023 Ermal Lu?i
				array_pop($path);
2160
			}
2161
		}
2162 ce0117f7 Colin Fleming
2163 f5881023 Ermal Lu?i
		return $q;
2164
	}
2165 a843b04f Ermal Luçi
2166 420b4538 Renato Botelho
	function copy_queue($interface, &$cflink) {
2167 a843b04f Ermal Luçi
2168 f5881023 Ermal Lu?i
		$cflink['name'] = $this->GetQname();
2169
		$cflink['interface'] = $interface;
2170
		$cflink['qlimit'] = trim($this->GetQlimit());
2171 61e047a5 Phil Davis
		if (empty($cflink['qlimit'])) {
2172 f5881023 Ermal Lu?i
			unset($cflink['qlimit']);
2173 61e047a5 Phil Davis
		}
2174 f5881023 Ermal Lu?i
		$cflink['priority'] = trim($this->GetQpriority());
2175 61e047a5 Phil Davis
		if (empty($cflink['priority'])) {
2176 f5881023 Ermal Lu?i
			unset($cflink['priority']);
2177 61e047a5 Phil Davis
		}
2178 f5881023 Ermal Lu?i
		$cflink['description'] = trim($this->GetDescription());
2179 61e047a5 Phil Davis
		if (empty($cflink['description'])) {
2180 f5881023 Ermal Lu?i
			unset($cflink['description']);
2181 61e047a5 Phil Davis
		}
2182 f5881023 Ermal Lu?i
		$cflink['bandwidth'] = $this->GetBandwidth();
2183
		$cflink['bandwidthtype'] = $this->GetBwscale();
2184
		$cflink['enabled'] = trim($this->GetEnabled());
2185 61e047a5 Phil Davis
		if (empty($cflink['enabled'])) {
2186 f5881023 Ermal Lu?i
			unset($cflink['enabled']);
2187 61e047a5 Phil Davis
		}
2188 f5881023 Ermal Lu?i
		$cflink['default'] = trim($this->GetDefault());
2189 61e047a5 Phil Davis
		if (empty($cflink['default'])) {
2190 f5881023 Ermal Lu?i
			unset($cflink['default']);
2191 61e047a5 Phil Davis
		}
2192 f5881023 Ermal Lu?i
		$cflink['red'] = trim($this->GetRed());
2193 61e047a5 Phil Davis
		if (empty($cflink['red'])) {
2194 f5881023 Ermal Lu?i
			unset($cflink['red']);
2195 61e047a5 Phil Davis
		}
2196 f5881023 Ermal Lu?i
		$cflink['rio'] = trim($this->GetRio());
2197 61e047a5 Phil Davis
		if (empty($cflink['rio'])) {
2198 f5881023 Ermal Lu?i
			unset($cflink['rio']);
2199 61e047a5 Phil Davis
		}
2200 f5881023 Ermal Lu?i
		$cflink['ecn'] = trim($this->GetEcn());
2201 61e047a5 Phil Davis
		if (empty($cflink['ecn'])) {
2202 f5881023 Ermal Lu?i
			unset($cflink['ecn']);
2203 61e047a5 Phil Davis
		}
2204 f5881023 Ermal Lu?i
		if ($this->GetLinkshare() <> "") {
2205
			if ($this->GetL_m1() <> "") {
2206
				$cflink['linkshare1'] = $this->GetL_m1();
2207
				$cflink['linkshare2'] = $this->GetL_d();
2208
				$cflink['linkshare'] = "on";
2209
			} else {
2210
				unset($cflink['linkshare1']);
2211
				unset($cflink['linkshare2']);
2212
				unset($cflink['linkshare']);
2213 fce82460 Ermal Luçi
			}
2214 f5881023 Ermal Lu?i
			if ($this->GetL_m2() <> "") {
2215
				$cflink['linkshare3'] = $this->GetL_m2();
2216
				$cflink['linkshare'] = "on";
2217
			} else {
2218
				unset($cflink['linkshare3']);
2219
				unset($cflink['linkshare']);
2220 92125c97 Ermal Luçi
			}
2221 f5881023 Ermal Lu?i
		}
2222
		if ($this->GetRealtime() <> "") {
2223
			if ($this->GetR_m1() <> "") {
2224
				$cflink['realtime1'] = $this->GetR_m1();
2225
				$cflink['realtime2'] = $this->GetR_d();
2226
				$cflink['realtime'] = "on";
2227
			} else {
2228
				unset($cflink['realtime1']);
2229 420b4538 Renato Botelho
				unset($cflink['realtime2']);
2230
				unset($cflink['realtime']);
2231 f5881023 Ermal Lu?i
			}
2232
			if ($this->GetR_m2() <> "") {
2233
				$cflink['realtime3'] = $this->GetR_m2();
2234
				$cflink['realtime'] = "on";
2235
			} else {
2236
				unset($cflink['realtime3']);
2237
				unset($cflink['realtime']);
2238 92125c97 Ermal Luçi
			}
2239 b7ff5e40 Scott Ullrich
		}
2240 f5881023 Ermal Lu?i
		if ($this->GetUpperlimit() <> "") {
2241
			if ($this->GetU_m1() <> "") {
2242
				$cflink['upperlimit1'] = $this->GetU_m1();
2243
				$cflink['upperlimit2'] = $this->GetU_d();
2244
				$cflink['upperlimit'] = "on";
2245
			} else {
2246
				unset($cflink['upperlimit']);
2247
				unset($cflink['upperlimit1']);
2248
				unset($cflink['upperlimit2']);
2249
			}
2250
			if ($this->GetU_m2() <> "") {
2251
				$cflink['upperlimit3'] = $this->GetU_m2();
2252
				$cflink['upperlimit'] = "on";
2253
			} else {
2254
				unset($cflink['upperlimit3']);
2255
				unset($cflink['upperlimit']);
2256
			}
2257 92125c97 Ermal Luçi
		}
2258 40de74f5 Ermal Luçi
2259 f5881023 Ermal Lu?i
		if (is_array($this->subqueues)) {
2260
			$cflinkp['queue'] = array();
2261
			foreach ($this->subqueues as $q) {
2262
				$cflink['queue'][$q->GetQname()] = array();
2263 ea51e9f8 Renato Botelho
				$q->copy_queue($interface, $cflink['queue'][$q->GetQname()]);
2264 f5881023 Ermal Lu?i
			}
2265
		}
2266
	}
2267
2268 420b4538 Renato Botelho
	function delete_queue() {
2269 f5881023 Ermal Lu?i
		unref_on_altq_queue_list($this->GetQname());
2270
		cleanup_queue_from_rules($this->GetQname());
2271
		$parent =& $this->GetParent();
2272 402012d9 Viktor G
		foreach ($this->subqueues as $q) {
2273 45eeb038 Luiz Otavio O Souza
			$q->delete_queue();
2274 402012d9 Viktor G
		}
2275 f5881023 Ermal Lu?i
		unset_object_by_reference($this->GetLink());
2276
	}
2277
2278
	/*
2279
	 * Should search even its children
2280
	 */
2281
	function &find_queue($interface, $qname) {
2282 61e047a5 Phil Davis
		if ($qname == $this->GetQname()) {
2283 f5881023 Ermal Lu?i
			return $this;
2284 61e047a5 Phil Davis
		}
2285 f5881023 Ermal Lu?i
2286
		foreach ($this->subqueues as $q) {
2287
			$result =& $q->find_queue("", $qname);
2288 61e047a5 Phil Davis
			if ($result) {
2289 f5881023 Ermal Lu?i
				return $result;
2290 61e047a5 Phil Davis
			}
2291 f5881023 Ermal Lu?i
		}
2292
	}
2293
2294
	function &find_parentqueue($interface, $qname) {
2295 61e047a5 Phil Davis
		if ($this->subqueues[$qname]) {
2296 f5881023 Ermal Lu?i
			return $this;
2297 61e047a5 Phil Davis
		}
2298 f5881023 Ermal Lu?i
		foreach ($this->subqueues as $q) {
2299
			$result = $q->find_parentqueue("", $qname);
2300 61e047a5 Phil Davis
			if ($result) {
2301 f5881023 Ermal Lu?i
				return $result;
2302 61e047a5 Phil Davis
			}
2303 f5881023 Ermal Lu?i
		}
2304
	}
2305 ce0117f7 Colin Fleming
2306 f5881023 Ermal Lu?i
	function validate_input($data, &$input_errors) {
2307
		parent::validate_input($data, $input_errors);
2308 ce0117f7 Colin Fleming
2309 f5881023 Ermal Lu?i
		$reqdfields[] = "bandwidth";
2310 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidth");
2311 f5881023 Ermal Lu?i
		$reqdfields[] = "bandwidthtype";
2312 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidthtype");
2313 f5881023 Ermal Lu?i
2314
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
2315 ce0117f7 Colin Fleming
2316 b0f0993d Viktor G
		if (isset($data['linkshare3']) && !empty($data['linkshare3'])) {
2317
			if ($data['bandwidth'] && !is_numeric($data['bandwidth'])) {
2318 dbaf21d4 Renato Botelho
				$input_errors[] = gettext("Bandwidth must be an integer.");
2319 61e047a5 Phil Davis
			}
2320 f5881023 Ermal Lu?i
2321 61e047a5 Phil Davis
			if ($data['bandwidth'] < 0) {
2322 dbaf21d4 Renato Botelho
				$input_errors[] = gettext("Bandwidth cannot be negative.");
2323 61e047a5 Phil Davis
			}
2324 f5881023 Ermal Lu?i
2325
			if ($data['bandwidthtype'] == "%") {
2326 b0f0993d Viktor G
				if (($data['bandwidth'] > 100) || ($data['bandwidth'] < 0)) {
2327 45eeb038 Luiz Otavio O Souza
					$input_errors[] = gettext("Bandwidth in percentage should be between 1 and 100.");
2328 61e047a5 Phil Davis
				}
2329 f5881023 Ermal Lu?i
			}
2330 92125c97 Ermal Luçi
		}
2331
2332 b0f0993d Viktor G
		if (!empty($data['upperlimit1']) && empty($data['upperlimit2'])) {
2333 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("upperlimit service curve defined but missing (d) value");
2334 61e047a5 Phil Davis
		}
2335 b0f0993d Viktor G
		if (!empty($data['upperlimit2']) && empty($data['upperlimit1'])) {
2336 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("upperlimit service curve defined but missing initial bandwidth (m1) value");
2337 61e047a5 Phil Davis
		}
2338 b0f0993d Viktor G
		if (!empty($data['upperlimit1']) && !is_valid_shaperbw($data['upperlimit1'])) {
2339 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("upperlimit m1 value needs to be Kb, Mb, Gb, or %");
2340 61e047a5 Phil Davis
		}
2341 b0f0993d Viktor G
		if (!empty($data['upperlimit2']) && !is_numeric($data['upperlimit2'])) {
2342 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("upperlimit d value needs to be numeric");
2343 61e047a5 Phil Davis
		}
2344 b0f0993d Viktor G
		if (!empty($data['upperlimit3']) && !is_valid_shaperbw($data['upperlimit3'])) {
2345 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("upperlimit m2 value needs to be Kb, Mb, Gb, or %");
2346 61e047a5 Phil Davis
		}
2347 a843b04f Ermal Luçi
2348 f5881023 Ermal Lu?i
		/*
2349 40de74f5 Ermal Luçi
		if (isset($data['upperlimit']) && $data['upperlimit3'] <> "" && $data['upperlimit1'] <> "") {
2350 f5881023 Ermal Lu?i
			$bw_1 = get_hfsc_bandwidth($this, $data['upperlimit1']);
2351
			$bw_2 = get_hfsc_bandwidth($this, $data['upperlimit3']);
2352 61e047a5 Phil Davis
			if (floatval($bw_1) < floatval($bw_2)) {
2353 f5881023 Ermal Lu?i
				$input_errors[] = ("upperlimit m1 cannot be smaller than m2");
2354 61e047a5 Phil Davis
			}
2355 40de74f5 Ermal Luçi
2356 61e047a5 Phil Davis
			if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2)))) {
2357 794195d1 Phil Davis
				$input_errors[] = ("upperlimit specification exceeds 80% of allowable allocation.");
2358 61e047a5 Phil Davis
			}
2359 40de74f5 Ermal Luçi
		}
2360 f5881023 Ermal Lu?i
		*/
2361 4de8f7ba Phil Davis
		if ($data['linkshare1'] <> "" && $data['linkshare2'] == "") {
2362 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("linkshare service curve defined but missing (d) value");
2363 61e047a5 Phil Davis
		}
2364 4de8f7ba Phil Davis
		if ($data['linkshare2'] <> "" && $data['linkshare1'] == "") {
2365 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("linkshare service curve defined but missing initial bandwidth (m1) value");
2366 61e047a5 Phil Davis
		}
2367
		if ($data['linkshare1'] <> "" && !is_valid_shaperbw($data['linkshare1'])) {
2368 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("linkshare m1 value needs to be Kb, Mb, Gb, or %");
2369 61e047a5 Phil Davis
		}
2370
		if ($data['linkshare2'] <> "" && !is_numeric($data['linkshare2'])) {
2371 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("linkshare d value needs to be numeric");
2372 61e047a5 Phil Davis
		}
2373
		if ($data['linkshare3'] <> "" && !is_valid_shaperbw($data['linkshare3'])) {
2374 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("linkshare m2 value needs to be Kb, Mb, Gb, or %");
2375 61e047a5 Phil Davis
		}
2376 4de8f7ba Phil Davis
		if ($data['realtime1'] <> "" && $data['realtime2'] == "") {
2377 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("realtime service curve defined but missing (d) value");
2378 61e047a5 Phil Davis
		}
2379 4de8f7ba Phil Davis
		if ($data['realtime2'] <> "" && $data['realtime1'] == "") {
2380 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("realtime service curve defined but missing initial bandwidth (m1) value");
2381 61e047a5 Phil Davis
		}
2382 40de74f5 Ermal Luçi
2383 f5881023 Ermal Lu?i
		/*
2384 a843b04f Ermal Luçi
		if (isset($data['linkshare']) && $data['linkshare3'] <> "" && $data['linkshare1'] <> "" && 0) {
2385 f5881023 Ermal Lu?i
			$bw_1 = get_hfsc_bandwidth($this, $data['linkshare1']);
2386 420b4538 Renato Botelho
			$bw_2 = get_hfsc_bandwidth($this, $data['linkshare3']);
2387 61e047a5 Phil Davis
			if (floatval($bw_1) < floatval($bw_2)) {
2388 420b4538 Renato Botelho
				$input_errors[] = ("linkshare m1 cannot be smaller than m2");
2389 61e047a5 Phil Davis
			}
2390 40de74f5 Ermal Luçi
2391 61e047a5 Phil Davis
			if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2)))) {
2392 420b4538 Renato Botelho
				$input_errors[] = ("linkshare specification exceeds 80% of allowable allocation.");
2393 61e047a5 Phil Davis
			}
2394 40de74f5 Ermal Luçi
		}
2395 f5881023 Ermal Lu?i
		*/
2396 a2f70da3 Ermal Luçi
2397 61e047a5 Phil Davis
		if ($data['realtime1'] <> "" && !is_valid_shaperbw($data['realtime1'])) {
2398 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("realtime m1 value needs to be Kb, Mb, Gb, or %");
2399 61e047a5 Phil Davis
		}
2400
		if ($data['realtime2'] <> "" && !is_numeric($data['realtime2'])) {
2401 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("realtime d value needs to be numeric");
2402 61e047a5 Phil Davis
		}
2403
		if ($data['realtime3'] <> "" && !is_valid_shaperbw($data['realtime3'])) {
2404 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("realtime m2 value needs to be Kb, Mb, Gb, or %");
2405 61e047a5 Phil Davis
		}
2406 40de74f5 Ermal Luçi
2407 f5881023 Ermal Lu?i
		/*
2408 a843b04f Ermal Luçi
		if (isset($data['realtime']) && $data['realtime3'] <> "" && $data['realtime1'] <> "" && 0) {
2409 f5881023 Ermal Lu?i
			$bw_1 = get_hfsc_bandwidth($this, $data['realtime1']);
2410 420b4538 Renato Botelho
			$bw_2 = get_hfsc_bandwidth($this, $data['realtime3']);
2411 61e047a5 Phil Davis
			if (floatval($bw_1) < floatval($bw_2)) {
2412 420b4538 Renato Botelho
				$input_errors[] = ("realtime m1 cannot be smaller than m2");
2413 61e047a5 Phil Davis
			}
2414 40de74f5 Ermal Luçi
2415 61e047a5 Phil Davis
			if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2)))) {
2416 794195d1 Phil Davis
				$input_errors[] = ("realtime specification exceeds 80% of allowable allocation.");
2417 61e047a5 Phil Davis
			}
2418 40de74f5 Ermal Luçi
		}
2419 f5881023 Ermal Lu?i
		*/
2420 061f78b1 Bill Marquette
	}
2421
2422 f5881023 Ermal Lu?i
	function ReadConfig(&$cflink) {
2423
		if (!empty($cflink['linkshare'])) {
2424
			if (!empty($cflink['linkshare1'])) {
2425 92125c97 Ermal Luçi
				$this->SetL_m1($cflink['linkshare1']);
2426 420b4538 Renato Botelho
				$this->SetL_d($cflink['linkshare2']);
2427 92125c97 Ermal Luçi
				$this->SetLinkshare();
2428 7ed9c6ac Ermal
			} else {
2429
				$this->SetL_m1("");
2430 420b4538 Renato Botelho
				$this->SetL_d("");
2431 7ed9c6ac Ermal
				$this->DisableLinkshare();
2432 92125c97 Ermal Luçi
			}
2433 f5881023 Ermal Lu?i
			if (!empty($cflink['linkshare3'])) {
2434 420b4538 Renato Botelho
				$this->SetL_m2($cflink['linkshare3']);
2435 92125c97 Ermal Luçi
				$this->SetLinkshare();
2436
			}
2437 61e047a5 Phil Davis
		} else {
2438 f5881023 Ermal Lu?i
			$this->DisableLinkshare();
2439 61e047a5 Phil Davis
		}
2440 f5881023 Ermal Lu?i
		if (!empty($cflink['realtime'])) {
2441 420b4538 Renato Botelho
			if (!empty($cflink['realtime1'])) {
2442
				$this->SetR_m1($cflink['realtime1']);
2443
				$this->SetR_d($cflink['realtime2']);
2444 92125c97 Ermal Luçi
				$this->SetRealtime();
2445 7ed9c6ac Ermal
			} else {
2446 420b4538 Renato Botelho
				$this->SetR_m1("");
2447
				$this->SetR_d("");
2448 7ed9c6ac Ermal
				$this->DisableRealtime();
2449 92125c97 Ermal Luçi
			}
2450 420b4538 Renato Botelho
			if (!empty($cflink['realtime3'])) {
2451
				$this->SetR_m2($cflink['realtime3']);
2452 92125c97 Ermal Luçi
				$this->SetRealtime();
2453
			}
2454 61e047a5 Phil Davis
		} else {
2455 420b4538 Renato Botelho
			$this->DisableRealtime();
2456 61e047a5 Phil Davis
		}
2457 f5881023 Ermal Lu?i
		if (!empty($cflink['upperlimit'])) {
2458 420b4538 Renato Botelho
			if (!empty($cflink['upperlimit1'])) {
2459
				$this->SetU_m1($cflink['upperlimit1']);
2460
				$this->SetU_d($cflink['upperlimit2']);
2461 92125c97 Ermal Luçi
				$this->SetUpperlimit();
2462 7ed9c6ac Ermal
			} else {
2463 420b4538 Renato Botelho
				$this->SetU_m1("");
2464
				$this->SetU_d("");
2465 7ed9c6ac Ermal
				$this->DisableUpperlimit();
2466 92125c97 Ermal Luçi
			}
2467 420b4538 Renato Botelho
			if (!empty($cflink['upperlimit3'])) {
2468
				$this->SetU_m2($cflink['upperlimit3']);
2469 92125c97 Ermal Luçi
				$this->SetUpperlimit();
2470
			}
2471 61e047a5 Phil Davis
		} else {
2472 f5881023 Ermal Lu?i
			$this->DisableUpperlimit();
2473 61e047a5 Phil Davis
		}
2474 92125c97 Ermal Luçi
		parent::ReadConfig($cflink);
2475 f5881023 Ermal Lu?i
	}
2476 197bfe96 Ermal Luçi
2477
	function build_tree() {
2478 1072b933 jim-p
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface() ."&amp;queue=" . htmlspecialchars($this->GetQname())."&amp;action=show";
2479 197bfe96 Ermal Luçi
		$tree .= "\" ";
2480 f5881023 Ermal Lu?i
		$tmpvalue = $this->GetDefault();
2481 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
2482 f5881023 Ermal Lu?i
			$tree .= " class=\"navlnk\"";
2483 61e047a5 Phil Davis
		}
2484 1072b933 jim-p
		$tree .= " >" . htmlspecialchars($this->GetQname()) . "</a>";
2485 197bfe96 Ermal Luçi
		if (is_array($this->subqueues)) {
2486
			$tree .= "<ul>";
2487 4de8f7ba Phil Davis
			foreach ($this->subqueues as $q) {
2488 197bfe96 Ermal Luçi
				$tree .= $q->build_tree();
2489 420b4538 Renato Botelho
			}
2490 197bfe96 Ermal Luçi
			$tree .= "</ul>";
2491
		}
2492
		$tree .= "</li>";
2493
		return $tree;
2494 061f78b1 Bill Marquette
	}
2495
2496 f5881023 Ermal Lu?i
	/* Even this should take children into consideration */
2497 9d0b0635 Ermal
	function build_rules(&$default = false) {
2498 197bfe96 Ermal Luçi
2499 f5881023 Ermal Lu?i
		$pfq_rule = " queue ". $this->qname;
2500 61e047a5 Phil Davis
		if ($this->GetInterface()) {
2501 f5881023 Ermal Lu?i
			$pfq_rule .= " on ".get_real_interface($this->GetInterface());
2502 61e047a5 Phil Davis
		}
2503
		if ($this->GetBandwidth() && $this->GetBwscale()) {
2504 f5881023 Ermal Lu?i
			$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
2505 61e047a5 Phil Davis
		}
2506 ce0117f7 Colin Fleming
2507 f5881023 Ermal Lu?i
		$tmpvalue = $this->GetQlimit();
2508 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
2509 f5881023 Ermal Lu?i
			$pfq_rule .= " qlimit " . $this->GetQlimit();
2510 61e047a5 Phil Davis
		}
2511 8edaa92c Ermal
		if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetCodel() || $this->GetRealtime() <> "" || $this->GetLinkshare() <> "" || $this->GetUpperlimit() <> "") {
2512 f5881023 Ermal Lu?i
			$pfq_rule .= " hfsc ( ";
2513
			$tmpvalue = $this->GetRed();
2514
			if (!empty($tmpvalue)) {
2515
				$comma = 1;
2516
				$pfq_rule .= " red ";
2517
			}
2518 ce0117f7 Colin Fleming
2519 f5881023 Ermal Lu?i
			$tmpvalue = $this->GetRio();
2520
			if (!empty($tmpvalue)) {
2521 61e047a5 Phil Davis
				if ($comma) {
2522 f5881023 Ermal Lu?i
					$pfq_rule .= " ,";
2523 61e047a5 Phil Davis
				}
2524 f5881023 Ermal Lu?i
				$comma = 1;
2525
				$pfq_rule .= " rio ";
2526
			}
2527
			$tmpvalue = $this->GetEcn();
2528
			if (!empty($tmpvalue)) {
2529 61e047a5 Phil Davis
				if ($comma) {
2530 f5881023 Ermal Lu?i
					$pfq_rule .= " ,";
2531 61e047a5 Phil Davis
				}
2532 f5881023 Ermal Lu?i
				$comma = 1;
2533
				$pfq_rule .= " ecn ";
2534
			}
2535 8edaa92c Ermal
			$tmpvalue = $this->GetCodel();
2536
			if (!empty($tmpvalue)) {
2537 61e047a5 Phil Davis
				if ($comma) {
2538 8edaa92c Ermal
					$pfq_rule .= " ,";
2539 61e047a5 Phil Davis
				}
2540 8edaa92c Ermal
				$comma = 1;
2541
				$pfq_rule .= " codel ";
2542
			}
2543 f5881023 Ermal Lu?i
			$tmpvalue = $this->GetDefault();
2544
			if (!empty($tmpvalue)) {
2545 61e047a5 Phil Davis
				if ($comma) {
2546 f5881023 Ermal Lu?i
					$pfq_rule .= " ,";
2547 61e047a5 Phil Davis
				}
2548 f5881023 Ermal Lu?i
				$comma = 1;
2549
				$pfq_rule .= " default ";
2550 ef8fca71 Ermal
				$default = true;
2551 f5881023 Ermal Lu?i
			}
2552
2553 4de8f7ba Phil Davis
			if ($this->GetRealtime() <> "") {
2554 61e047a5 Phil Davis
				if ($comma) {
2555 f5881023 Ermal Lu?i
					$pfq_rule .= " , ";
2556 61e047a5 Phil Davis
				}
2557 4de8f7ba Phil Davis
				if ($this->GetR_m1() <> "" && $this->GetR_d() <> "" && $this->GetR_m2() <> "") {
2558 f5881023 Ermal Lu?i
					$pfq_rule .= " realtime (".$this->GetR_m1() . ", " . $this->GetR_d().", ". $this->GetR_m2() .") ";
2559 4de8f7ba Phil Davis
				} else if ($this->GetR_m2() <> "") {
2560 92125c97 Ermal Luçi
					$pfq_rule .= " realtime " . $this->GetR_m2();
2561 61e047a5 Phil Davis
				}
2562 197bfe96 Ermal Luçi
				$comma = 1;
2563
			}
2564 f5881023 Ermal Lu?i
			if ($this->GetLinkshare() <> "") {
2565 61e047a5 Phil Davis
				if ($comma) {
2566 197bfe96 Ermal Luçi
					$pfq_rule .= " ,";
2567 61e047a5 Phil Davis
				}
2568
				if ($this->GetL_m1() <> "" && $this->GetL_d() <> "" && $this->GetL_m2() <> "") {
2569 f5881023 Ermal Lu?i
					$pfq_rule .= " linkshare (".$this->GetL_m1(). ", ". $this->GetL_d(). ", ". $this->GetL_m2(). ") ";
2570 61e047a5 Phil Davis
				} else if ($this->GetL_m2() <> "") {
2571 92125c97 Ermal Luçi
					$pfq_rule .= " linkshare " . $this->GetL_m2() . " ";
2572 61e047a5 Phil Davis
				}
2573 197bfe96 Ermal Luçi
				$comma = 1;
2574
			}
2575 f5881023 Ermal Lu?i
			if ($this->GetUpperlimit() <> "") {
2576 61e047a5 Phil Davis
				if ($comma) {
2577 197bfe96 Ermal Luçi
					$pfq_rule .= " ,";
2578 61e047a5 Phil Davis
				}
2579
				if ($this->GetU_m1() <> "" && $this->GetU_d() <> "" && $this->GetU_m2() <> "") {
2580 92125c97 Ermal Luçi
							$pfq_rule .= " upperlimit (".$this->GetU_m1().", ". $this->GetU_d().", ". $this->GetU_m2(). ") ";
2581 61e047a5 Phil Davis
				} else if ($this->GetU_m2() <> "") {
2582 92125c97 Ermal Luçi
					$pfq_rule .= " upperlimit " . $this->GetU_m2() . " ";
2583 61e047a5 Phil Davis
				}
2584 197bfe96 Ermal Luçi
			}
2585 f5881023 Ermal Lu?i
			$pfq_rule .= " ) ";
2586
		}
2587
		if (count($this->subqueues)) {
2588
			$i = count($this->subqueues);
2589
			$pfq_rule .= " { ";
2590
			foreach ($this->subqueues as $qkey => $qnone) {
2591
				if ($i > 1) {
2592
					$i--;
2593
					$pfq_rule .= " {$qkey}, ";
2594 61e047a5 Phil Davis
				} else {
2595 f5881023 Ermal Lu?i
					$pfq_rule .= " {$qkey} ";
2596 61e047a5 Phil Davis
				}
2597 f5881023 Ermal Lu?i
			}
2598
			$pfq_rule .= " } \n";
2599 61e047a5 Phil Davis
			foreach ($this->subqueues as $q) {
2600 ea51e9f8 Renato Botelho
				$pfq_rule .= $q->build_rules($default);
2601 61e047a5 Phil Davis
			}
2602 92125c97 Ermal Luçi
		}
2603 197bfe96 Ermal Luçi
2604 420b4538 Renato Botelho
		$pfq_rule .= " \n";
2605 ce0117f7 Colin Fleming
2606 f5881023 Ermal Lu?i
		return $pfq_rule;
2607
	}
2608
2609 197bfe96 Ermal Luçi
	function build_javascript() {
2610 806942d0 Stephen Beaver
2611 9ddd492c Stephen Beaver
		$javascript = <<<EOJS
2612
<script type="text/javascript">
2613 806942d0 Stephen Beaver
//<![CDATA[
2614 9ddd492c Stephen Beaver
	events.push(function(){
2615 806942d0 Stephen Beaver
2616
		// Disables the specified input element
2617
		function disableInput(id, disable) {
2618
			$('#' + id).prop("disabled", disable);
2619
		}
2620
2621
		// Upperlimit
2622
		function enable_upperlimit() {
2623
			disableInput('upperlimit1', !$('#upperlimit').prop('checked'));
2624
			disableInput('upperlimit2', !$('#upperlimit').prop('checked'));
2625
			disableInput('upperlimit3', !$('#upperlimit').prop('checked'));
2626
		}
2627
2628
		$('#upperlimit').click(function () {
2629
			enable_upperlimit();
2630
		});
2631
2632
		enable_upperlimit();
2633
2634
		// realtime
2635
		function enable_realtime() {
2636
			disableInput('realtime1', !$('#realtime').prop('checked'));
2637
			disableInput('realtime2', !$('#realtime').prop('checked'));
2638
			disableInput('realtime3', !$('#realtime').prop('checked'));
2639
		}
2640
2641
		$('#realtime').click(function () {
2642
			enable_realtime();
2643
		});
2644
2645
		enable_realtime();
2646
2647
		// linkshare
2648
		function enable_linkshare() {
2649
			disableInput('linkshare1', !$('#linkshare').prop('checked'));
2650
			disableInput('linkshare2', !$('#linkshare').prop('checked'));
2651
			disableInput('linkshare3', !$('#linkshare').prop('checked'));
2652
		}
2653
2654
		$('#linkshare').click(function () {
2655
			enable_linkshare();
2656
		});
2657
2658
		enable_linkshare();
2659 9ddd492c Stephen Beaver
	});
2660 806942d0 Stephen Beaver
//]]>
2661
</script>
2662 9ddd492c Stephen Beaver
EOJS;
2663 92125c97 Ermal Luçi
2664 197bfe96 Ermal Luçi
		return $javascript;
2665
	}
2666 061f78b1 Bill Marquette
2667 f5881023 Ermal Lu?i
	function build_form() {
2668 806942d0 Stephen Beaver
2669 aef9d8fe Stephen Beaver
		$sform = parent::build_form();
2670 806942d0 Stephen Beaver
2671 aef9d8fe Stephen Beaver
		$section = new Form_Section('Service Curve (sc)');
2672
2673
		$group = new Form_Group('Bandwidth');
2674 806942d0 Stephen Beaver
2675 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2676
			'bandwidth',
2677
			null,
2678
			'number',
2679 54a217f0 Steve Beaver
			$this->GetBandwidth(),
2680
			['step' => 'any', 'min' => '0.000']
2681 aef9d8fe Stephen Beaver
		));
2682 806942d0 Stephen Beaver
2683 aef9d8fe Stephen Beaver
		$group->add(new Form_Select(
2684
			'bandwidthtype',
2685
			null,
2686 9abbcb4b Viktor G
			$this->FormGetBwscale(),
2687 bfc94df0 Phil Davis
			array('Kb' => 'Kbit/s',
2688
				  'Mb' => 'Mbit/s',
2689
				  'Gb' => 'Gbit/s',
2690
				  'b' => 'Bit/s',
2691 820519e5 Stephen Beaver
				  '%' => '%')
2692 aef9d8fe Stephen Beaver
		));
2693 806942d0 Stephen Beaver
2694 aef9d8fe Stephen Beaver
		$group->setHelp('Choose the amount of bandwidth for this queue');
2695 806942d0 Stephen Beaver
2696 aef9d8fe Stephen Beaver
		$section->add($group);
2697 806942d0 Stephen Beaver
2698 aef9d8fe Stephen Beaver
		$group = new Form_Group('Max bandwidth for queue.');
2699 806942d0 Stephen Beaver
2700 aef9d8fe Stephen Beaver
		$group->add(new Form_Checkbox(
2701
			'upperlimit',
2702
			null,
2703
			'Upper Limit',
2704
			($this->GetUpperlimit()<> "")
2705 806942d0 Stephen Beaver
		));
2706
2707 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2708
			'upperlimit1',
2709
			null,
2710
			'text',
2711
			$this->GetU_m1()
2712 f7b9f8ee Stephen Beaver
		))->setHelp('m1');
2713 806942d0 Stephen Beaver
2714 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2715
			'upperlimit2',
2716
			null,
2717
			'text',
2718
			$this->GetU_d()
2719 f7b9f8ee Stephen Beaver
		))->setHelp('d');
2720 b37b4034 Phil Davis
2721 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2722
			'upperlimit3',
2723
			null,
2724
			'text',
2725
			$this->GetU_m2()
2726 f7b9f8ee Stephen Beaver
		))->setHelp('m2');
2727 806942d0 Stephen Beaver
2728
2729
		$section->add($group);
2730
2731 aef9d8fe Stephen Beaver
		$group = new Form_Group('Min bandwidth for queue.');
2732 806942d0 Stephen Beaver
2733 aef9d8fe Stephen Beaver
		$group->add(new Form_Checkbox(
2734
			'realtime',
2735
			null,
2736 9ddd492c Stephen Beaver
			'Real Time',
2737 aef9d8fe Stephen Beaver
			($this->GetRealtime()<> "")
2738 806942d0 Stephen Beaver
		));
2739
2740 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2741
			'realtime1',
2742
			null,
2743
			'text',
2744
			$this->GetR_m1()
2745 f7b9f8ee Stephen Beaver
		))->setHelp('m1');
2746 806942d0 Stephen Beaver
2747 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2748
			'realtime2',
2749
			null,
2750
			'text',
2751
			$this->GetR_d()
2752 f7b9f8ee Stephen Beaver
		))->setHelp('d');
2753 b37b4034 Phil Davis
2754 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2755
			'realtime3',
2756
			null,
2757
			'text',
2758
			$this->GetR_m2()
2759 f7b9f8ee Stephen Beaver
		))->setHelp('m2');
2760 806942d0 Stephen Beaver
2761 aef9d8fe Stephen Beaver
		$section->add($group);
2762 806942d0 Stephen Beaver
2763 aef9d8fe Stephen Beaver
		$group = new Form_Group('B/W share of a backlogged queue.');
2764 806942d0 Stephen Beaver
2765 aef9d8fe Stephen Beaver
		$group->add(new Form_Checkbox(
2766
			'linkshare',
2767
			null,
2768
			'Link Share',
2769
			($this->GetLinkshare()<> "")
2770 806942d0 Stephen Beaver
		));
2771
2772 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2773
			'linkshare1',
2774
			null,
2775
			'text',
2776
			$this->GetL_m1()
2777 f7b9f8ee Stephen Beaver
		))->setHelp('m1');
2778 806942d0 Stephen Beaver
2779 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2780
			'linkshare2',
2781
			null,
2782
			'text',
2783
			$this->GetL_d()
2784 f7b9f8ee Stephen Beaver
		))->setHelp('d');
2785 b37b4034 Phil Davis
2786 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
2787
			'linkshare3',
2788
			null,
2789
			'text',
2790
			$this->GetL_m2()
2791 f7b9f8ee Stephen Beaver
		))->setHelp('m2');
2792 806942d0 Stephen Beaver
2793 08dbe1c5 Phil Davis
		$group->sethelp('Bandwidth share overrides priority.%s' .
2794 aef9d8fe Stephen Beaver
						'The format for service curve specifications is (m1, d, m2). m2 controls the bandwidth assigned to the queue. ' .
2795
						'm1 and d are optional and can be used to control the initial bandwidth assignment. ' .
2796 08dbe1c5 Phil Davis
						'For the first d milliseconds the queue gets the bandwidth given as m1, afterwards the value given in m2.',
2797
						'<br />');
2798 806942d0 Stephen Beaver
2799 aef9d8fe Stephen Beaver
		$section->add($group);
2800 806942d0 Stephen Beaver
2801 aef9d8fe Stephen Beaver
		$sform->add($section);
2802 806942d0 Stephen Beaver
2803
		return($sform);
2804 f5881023 Ermal Lu?i
	}
2805 197bfe96 Ermal Luçi
2806 420b4538 Renato Botelho
	function update_altq_queue_data(&$data) {
2807 197bfe96 Ermal Luçi
		$this->ReadConfig($data);
2808 061f78b1 Bill Marquette
	}
2809
2810 92125c97 Ermal Luçi
	function wconfig() {
2811 197bfe96 Ermal Luçi
		$cflink =& get_reference_to_me_in_config($this->GetLink());
2812 61e047a5 Phil Davis
		if (!is_array($cflink)) {
2813 92125c97 Ermal Luçi
			$cflink = array();
2814 61e047a5 Phil Davis
		}
2815 f5881023 Ermal Lu?i
		$cflink['name'] = $this->GetQname();
2816
		$cflink['interface'] = $this->GetInterface();
2817
		$cflink['qlimit'] = trim($this->GetQlimit());
2818 61e047a5 Phil Davis
		if (empty($cflink['qlimit'])) {
2819 f5881023 Ermal Lu?i
			unset($cflink['qlimit']);
2820 61e047a5 Phil Davis
		}
2821 f5881023 Ermal Lu?i
		$cflink['priority'] = $this->GetQpriority();
2822 41799195 PiBa-NL
		if (!is_numericint($cflink['priority'])) {
2823 f5881023 Ermal Lu?i
			unset($cflink['priority']);
2824 61e047a5 Phil Davis
		}
2825 f5881023 Ermal Lu?i
		$cflink['description'] = $this->GetDescription();
2826 61e047a5 Phil Davis
		if (empty($cflink['description'])) {
2827 f5881023 Ermal Lu?i
			unset($cflink['description']);
2828 61e047a5 Phil Davis
		}
2829 f5881023 Ermal Lu?i
		$cflink['bandwidth'] = $this->GetBandwidth();
2830
		$cflink['bandwidthtype'] = $this->GetBwscale();
2831
		$cflink['enabled'] = $this->GetEnabled();
2832 61e047a5 Phil Davis
		if (empty($cflink['enabled'])) {
2833 f5881023 Ermal Lu?i
			unset($cflink['enabled']);
2834 61e047a5 Phil Davis
		}
2835 f5881023 Ermal Lu?i
		$cflink['default'] = $this->GetDefault();
2836 61e047a5 Phil Davis
		if (empty($cflink['default'])) {
2837 f5881023 Ermal Lu?i
			unset($cflink['default']);
2838 61e047a5 Phil Davis
		}
2839 f5881023 Ermal Lu?i
		$cflink['red'] = trim($this->GetRed());
2840 61e047a5 Phil Davis
		if (empty($cflink['red'])) {
2841 f5881023 Ermal Lu?i
			unset($cflink['red']);
2842 61e047a5 Phil Davis
		}
2843 f5881023 Ermal Lu?i
		$cflink['rio'] = $this->GetRio();
2844 61e047a5 Phil Davis
		if (empty($cflink['rio'])) {
2845 f5881023 Ermal Lu?i
			unset($cflink['rio']);
2846 61e047a5 Phil Davis
		}
2847 f5881023 Ermal Lu?i
		$cflink['ecn'] = trim($this->GetEcn());
2848 61e047a5 Phil Davis
		if (empty($cflink['ecn'])) {
2849 f5881023 Ermal Lu?i
			unset($cflink['ecn']);
2850 61e047a5 Phil Davis
		}
2851 9f6919e6 Richard Connon
		$cflink['codel'] = trim($this->GetCodel());
2852 61e047a5 Phil Davis
		if (empty($cflink['codel'])) {
2853 9f6919e6 Richard Connon
			unset($cflink['codel']);
2854 61e047a5 Phil Davis
		}
2855 f5881023 Ermal Lu?i
		if ($this->GetLinkshare() <> "") {
2856
			if ($this->GetL_m1() <> "") {
2857
				$cflink['linkshare1'] = $this->GetL_m1();
2858
				$cflink['linkshare2'] = $this->GetL_d();
2859
				$cflink['linkshare'] = "on";
2860
			} else {
2861
				unset($cflink['linkshare']);
2862
				unset($cflink['linkshare1']);
2863
				unset($cflink['linkshare2']);
2864
			}
2865
			if ($this->GetL_m2() <> "") {
2866
				$cflink['linkshare3'] = $this->GetL_m2();
2867
				$cflink['linkshare'] = "on";
2868
			} else {
2869
				unset($cflink['linkshare']);
2870
				unset($cflink['linkshare3']);
2871
			}
2872
		} else {
2873
			unset($cflink['linkshare']);
2874
			unset($cflink['linkshare1']);
2875
			unset($cflink['linkshare2']);
2876
			unset($cflink['linkshare3']);
2877
		}
2878
		if ($this->GetRealtime() <> "") {
2879
			if ($this->GetR_m1() <> "") {
2880
				$cflink['realtime1'] = $this->GetR_m1();
2881
				$cflink['realtime2'] = $this->GetR_d();
2882
				$cflink['realtime'] = "on";
2883
			} else {
2884
				unset($cflink['realtime']);
2885
				unset($cflink['realtime1']);
2886
				unset($cflink['realtime2']);
2887
			}
2888
			if ($this->GetR_m2() <> "") {
2889
				$cflink['realtime3'] = $this->GetR_m2();
2890
				$cflink['realtime'] = "on";
2891
			} else {
2892
				unset($cflink['realtime']);
2893
				unset($cflink['realtime3']);
2894
			}
2895
		} else {
2896
			unset($cflink['realtime']);
2897
			unset($cflink['realtime1']);
2898
			unset($cflink['realtime2']);
2899
			unset($cflink['realtime3']);
2900
		}
2901
		if ($this->GetUpperlimit() <> "") {
2902
			if ($this->GetU_m1() <> "") {
2903
				$cflink['upperlimit1'] = $this->GetU_m1();
2904
				$cflink['upperlimit2'] = $this->GetU_d();
2905
				$cflink['upperlimit'] = "on";
2906
			} else {
2907
				unset($cflink['upperlimit']);
2908
				unset($cflink['upperlimit1']);
2909
				unset($cflink['upperlimit2']);
2910
			}
2911
			if ($this->GetU_m2() <> "") {
2912
				$cflink['upperlimit3'] = $this->GetU_m2();
2913
				$cflink['upperlimit'] = "on";
2914
			} else {
2915
				unset($cflink['upperlimit']);
2916
				unset($cflink['upperlimit3']);
2917
			}
2918
		} else {
2919
			unset($cflink['upperlimit']);
2920
			unset($cflink['upperlimit1']);
2921
			unset($cflink['upperlimit2']);
2922
			unset($cflink['upperlimit3']);
2923 197bfe96 Ermal Luçi
		}
2924
	}
2925 f5881023 Ermal Lu?i
}
2926 061f78b1 Bill Marquette
2927 197bfe96 Ermal Luçi
class cbq_queue extends priq_queue {
2928 f5881023 Ermal Lu?i
	var $qborrow = "";
2929 061f78b1 Bill Marquette
2930 197bfe96 Ermal Luçi
	function GetBorrow() {
2931
		return $this->qborrow;
2932 061f78b1 Bill Marquette
	}
2933 197bfe96 Ermal Luçi
	function SetBorrow($borrow) {
2934
		$this->qborrow = $borrow;
2935
	}
2936 70b139a3 Chris Buechler
	function CanHaveChildren() {
2937 f5881023 Ermal Lu?i
		return true;
2938 92125c97 Ermal Luçi
	}
2939 197bfe96 Ermal Luçi
2940 92125c97 Ermal Luçi
	function &add_queue($interface, &$qname, &$path, &$input_errors) {
2941 197bfe96 Ermal Luçi
2942 61e047a5 Phil Davis
		if (!is_array($this->subqueues)) {
2943 f5881023 Ermal Lu?i
			$this->subqueues = array();
2944 61e047a5 Phil Davis
		}
2945 5c4fcabc Renato Botelho
		$__tmp_q = new cbq_queue(); $q =& $__tmp_q;
2946 197bfe96 Ermal Luçi
		$q->SetInterface($this->GetInterface());
2947 ea51e9f8 Renato Botelho
		$q->SetParent($this);
2948 92125c97 Ermal Luçi
		$q->ReadConfig($qname);
2949 420b4538 Renato Botelho
		$q->validate_input($qname, $input_errors);
2950 40de74f5 Ermal Luçi
2951 197bfe96 Ermal Luçi
		$q->SetEnabled("on");
2952 92125c97 Ermal Luçi
		$q->SetLink($path);
2953
		$this->subqueues[$q->GetQName()] = &$q;
2954 197bfe96 Ermal Luçi
		ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
2955
		if (is_array($qname['queue'])) {
2956 f5881023 Ermal Lu?i
			foreach ($qname['queue'] as $key1 => $que) {
2957
				array_push($path, $key1);
2958 ea51e9f8 Renato Botelho
				$q->add_queue($q->GetInterface(), $que, $path, $input_errors);
2959 f5881023 Ermal Lu?i
				array_pop($path);
2960
			}
2961 92125c97 Ermal Luçi
		}
2962 197bfe96 Ermal Luçi
2963
		return $q;
2964 f5881023 Ermal Lu?i
	}
2965 a843b04f Ermal Luçi
2966 f5881023 Ermal Lu?i
	function copy_queue($interface, &$cflink) {
2967 a843b04f Ermal Luçi
2968 f5881023 Ermal Lu?i
		$cflink['interface'] = $interface;
2969
		$cflink['qlimit'] = trim($this->GetQlimit());
2970 61e047a5 Phil Davis
		if (empty($clink['qlimit'])) {
2971 f5881023 Ermal Lu?i
			unset($cflink['qlimit']);
2972 61e047a5 Phil Davis
		}
2973 f5881023 Ermal Lu?i
		$cflink['priority'] = trim($this->GetQpriority());
2974 41799195 PiBa-NL
		if (!is_numeric($cflink['priority'])) {
2975 f5881023 Ermal Lu?i
			unset($cflink['priority']);
2976 61e047a5 Phil Davis
		}
2977 f5881023 Ermal Lu?i
		$cflink['name'] = $this->GetQname();
2978
		$cflink['description'] = trim($this->GetDescription());
2979 61e047a5 Phil Davis
		if (empty($cflink['description'])) {
2980 f5881023 Ermal Lu?i
			unset($cflink['description']);
2981 61e047a5 Phil Davis
		}
2982 f5881023 Ermal Lu?i
		$cflink['bandwidth'] = $this->GetBandwidth();
2983
		$cflink['bandwidthtype'] = $this->GetBwscale();
2984
		$cflink['enabled'] = trim($this->GetEnabled());
2985 61e047a5 Phil Davis
		if (empty($cflink['enabled'])) {
2986 f5881023 Ermal Lu?i
			unset($cflink['enabled']);
2987 61e047a5 Phil Davis
		}
2988 f5881023 Ermal Lu?i
		$cflink['default'] = trim($this->GetDefault());
2989 61e047a5 Phil Davis
		if (empty($cflink['default'])) {
2990 f5881023 Ermal Lu?i
			unset($cflink['default']);
2991 61e047a5 Phil Davis
		}
2992 f5881023 Ermal Lu?i
		$cflink['red'] = trim($this->GetRed());
2993 61e047a5 Phil Davis
		if (empty($cflink['red'])) {
2994 f5881023 Ermal Lu?i
			unset($cflink['red']);
2995 61e047a5 Phil Davis
		}
2996 f5881023 Ermal Lu?i
		$cflink['rio'] = trim($this->GetRio());
2997 61e047a5 Phil Davis
		if (empty($cflink['rio'])) {
2998 f5881023 Ermal Lu?i
			unset($cflink['rio']);
2999 61e047a5 Phil Davis
		}
3000 f5881023 Ermal Lu?i
		$cflink['ecn'] = trim($this->GetEcn());
3001 61e047a5 Phil Davis
		if (empty($cflink['ecn'])) {
3002 f5881023 Ermal Lu?i
			unset($cflink['ecn']);
3003 61e047a5 Phil Davis
		}
3004 f5881023 Ermal Lu?i
		$cflink['borrow'] = trim($this->GetBorrow());
3005 61e047a5 Phil Davis
		if (empty($cflink['borrow'])) {
3006 f5881023 Ermal Lu?i
			unset($cflink['borrow']);
3007 61e047a5 Phil Davis
		}
3008 f5881023 Ermal Lu?i
		if (is_array($this->queues)) {
3009
			$cflinkp['queue'] = array();
3010
			foreach ($this->subqueues as $q) {
3011
				$cflink['queue'][$q->GetQname()] = array();
3012 ea51e9f8 Renato Botelho
				$q->copy_queue($interface, $cflink['queue'][$q->GetQname()]);
3013 f5881023 Ermal Lu?i
			}
3014 a843b04f Ermal Luçi
		}
3015 f5881023 Ermal Lu?i
	}
3016 ce0117f7 Colin Fleming
3017 f5881023 Ermal Lu?i
	/*
3018
	 * Should search even its children
3019
	 */
3020
	function &find_queue($interface, $qname) {
3021 61e047a5 Phil Davis
		if ($qname == $this->GetQname()) {
3022 f5881023 Ermal Lu?i
			return $this;
3023 61e047a5 Phil Davis
		}
3024 f5881023 Ermal Lu?i
		foreach ($this->subqueues as $q) {
3025
			$result =& $q->find_queue("", $qname);
3026 61e047a5 Phil Davis
			if ($result) {
3027 f5881023 Ermal Lu?i
				return $result;
3028 61e047a5 Phil Davis
			}
3029 92125c97 Ermal Luçi
		}
3030 f5881023 Ermal Lu?i
	}
3031 197bfe96 Ermal Luçi
3032
	function &find_parentqueue($interface, $qname) {
3033 61e047a5 Phil Davis
		if ($this->subqueues[$qname]) {
3034 f5881023 Ermal Lu?i
			return $this;
3035 61e047a5 Phil Davis
		}
3036 f5881023 Ermal Lu?i
		foreach ($this->subqueues as $q) {
3037
			$result = $q->find_parentqueue("", $qname);
3038 61e047a5 Phil Davis
			if ($result) {
3039 197bfe96 Ermal Luçi
				return $result;
3040 61e047a5 Phil Davis
			}
3041 197bfe96 Ermal Luçi
		}
3042 f5881023 Ermal Lu?i
	}
3043 197bfe96 Ermal Luçi
3044 f5881023 Ermal Lu?i
	function delete_queue() {
3045
		unref_on_altq_queue_list($this->GetQname());
3046
		cleanup_queue_from_rules($this->GetQname());
3047 402012d9 Viktor G
		foreach ($this->subqueues as $q) {
3048 45eeb038 Luiz Otavio O Souza
			$q->delete_queue();
3049 402012d9 Viktor G
		}
3050 f5881023 Ermal Lu?i
		unset_object_by_reference($this->GetLink());
3051
	}
3052 ce0117f7 Colin Fleming
3053 197bfe96 Ermal Luçi
	function validate_input($data, &$input_errors) {
3054
		parent::validate_input($data, $input_errors);
3055 ce0117f7 Colin Fleming
3056 2c072899 jim-p
		$reqdfields[] = "bandwidth";
3057 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidth");
3058 2c072899 jim-p
		$reqdfields[] = "bandwidthtype";
3059 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidthtype");
3060 061f78b1 Bill Marquette
3061 40de74f5 Ermal Luçi
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
3062 7ccff001 Viktor G
3063
		if ($data['priority'] > 7) {
3064
			$input_errors[] = gettext("Priority must be an integer between 0 and 7.");
3065
		}
3066
3067
		$parent = $this->GetParent();
3068
		if (method_exists($parent, 'GetParent') && ($parent->GetBorrow() != "on") &&
3069
		    ($data['borrow'] == 'yes')) {
3070
			$input_errors[] = gettext("You cannot set 'Borrow' if the parent queue also does not borrow.");
3071
		}
3072 92125c97 Ermal Luçi
	}
3073 f5881023 Ermal Lu?i
3074
	function ReadConfig(&$q) {
3075
		parent::ReadConfig($q);
3076 61e047a5 Phil Davis
		if (!empty($q['borrow'])) {
3077 197bfe96 Ermal Luçi
			$this->SetBorrow("on");
3078 61e047a5 Phil Davis
		} else {
3079 7ed9c6ac Ermal
			$this->SetBorrow("");
3080 61e047a5 Phil Davis
		}
3081 f5881023 Ermal Lu?i
	}
3082 ce0117f7 Colin Fleming
3083 197bfe96 Ermal Luçi
	function build_javascript() {
3084
		return parent::build_javascript();
3085
	}
3086 061f78b1 Bill Marquette
3087 197bfe96 Ermal Luçi
	function build_tree() {
3088 1072b933 jim-p
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface()."&amp;queue=" . htmlspecialchars($this->GetQname())."&amp;action=show";
3089 f5881023 Ermal Lu?i
		$tree .= "\" ";
3090
		$tmpvalue = trim($this->GetDefault());
3091 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
3092 f5881023 Ermal Lu?i
			$tree .= " class=\"navlnk\"";
3093 61e047a5 Phil Davis
		}
3094 1072b933 jim-p
		$tree .= " >" . htmlspecialchars($this->GetQname()) . "</a>";
3095 f5881023 Ermal Lu?i
		if (is_array($this->subqueues)) {
3096
			$tree .= "<ul>";
3097 4de8f7ba Phil Davis
			foreach ($this->subqueues as $q) {
3098 f5881023 Ermal Lu?i
				$tree .= $q->build_tree();
3099 420b4538 Renato Botelho
			}
3100 f5881023 Ermal Lu?i
			$tree .= "</ul>";
3101
		}
3102
		$tree .= "</li>";
3103
		return $tree;
3104 197bfe96 Ermal Luçi
	}
3105 ce0117f7 Colin Fleming
3106 70b139a3 Chris Buechler
	/* Even this should take children into consideration */
3107 9d0b0635 Ermal
	function build_rules(&$default = false) {
3108 f5881023 Ermal Lu?i
		$pfq_rule = "queue ". $this->qname;
3109 61e047a5 Phil Davis
		if ($this->GetInterface()) {
3110 f5881023 Ermal Lu?i
			$pfq_rule .= " on ".get_real_interface($this->GetInterface());
3111 61e047a5 Phil Davis
		}
3112
		if ($this->GetBandwidth() && $this->GetBwscale()) {
3113 f5881023 Ermal Lu?i
			$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
3114 61e047a5 Phil Davis
		}
3115 f5881023 Ermal Lu?i
		$tmpvalue = $this->GetQpriority();
3116 41799195 PiBa-NL
		if (is_numeric($tmpvalue)) {
3117 f5881023 Ermal Lu?i
			$pfq_rule .= " priority " . $this->GetQpriority();
3118 61e047a5 Phil Davis
		}
3119 f5881023 Ermal Lu?i
		$tmpvalue = trim($this->GetQlimit());
3120 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
3121 f5881023 Ermal Lu?i
			$pfq_rule .= " qlimit " . $this->GetQlimit();
3122 61e047a5 Phil Davis
		}
3123 8edaa92c Ermal
		if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetBorrow() || $this->GetCodel()) {
3124 f5881023 Ermal Lu?i
			$pfq_rule .= " cbq ( ";
3125
			$tmpvalue = trim($this->GetRed());
3126
			if (!empty($tmpvalue)) {
3127
				$comma = 1;
3128
				$pfq_rule .= " red ";
3129
			}
3130 8edaa92c Ermal
			$tmpvalue = trim($this->GetCodel());
3131
			if (!empty($tmpvalue)) {
3132
				$comma = 1;
3133
				$pfq_rule .= " codel ";
3134
			}
3135 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetRio());
3136
			if (!empty($tmpvalue)) {
3137 61e047a5 Phil Davis
				if ($comma) {
3138 f5881023 Ermal Lu?i
					$pfq_rule .= " ,";
3139 61e047a5 Phil Davis
				}
3140 f5881023 Ermal Lu?i
				$comma = 1;
3141
				$pfq_rule .= " rio ";
3142
			}
3143
			$tmpvalue = trim($this->GetEcn());
3144
			if (!empty($tmpvalue)) {
3145 61e047a5 Phil Davis
				if ($comma) {
3146 f5881023 Ermal Lu?i
					$pfq_rule .= " ,";
3147 61e047a5 Phil Davis
				}
3148 f5881023 Ermal Lu?i
				$comma = 1;
3149
				$pfq_rule .= " ecn ";
3150
			}
3151
			$tmpvalue = trim($this->GetDefault());
3152
			if (!empty($tmpvalue)) {
3153 61e047a5 Phil Davis
				if ($comma) {
3154 f5881023 Ermal Lu?i
					$pfq_rule .= " ,";
3155 61e047a5 Phil Davis
				}
3156 f5881023 Ermal Lu?i
				$comma = 1;
3157
				$pfq_rule .= " default ";
3158 ef8fca71 Ermal
				$default = true;
3159 f5881023 Ermal Lu?i
			}
3160
			$tmpvalue = trim($this->GetBorrow());
3161
			if (!empty($tmpvalue)) {
3162 61e047a5 Phil Davis
				if ($comma) {
3163 f5881023 Ermal Lu?i
					$pfq_rule .= ", ";
3164 61e047a5 Phil Davis
				}
3165 f5881023 Ermal Lu?i
				$pfq_rule .= " borrow ";
3166 92125c97 Ermal Luçi
			}
3167 f5881023 Ermal Lu?i
			$pfq_rule .= " ) ";
3168 420b4538 Renato Botelho
		}
3169 f5881023 Ermal Lu?i
		if (count($this->subqueues)) {
3170
			$i = count($this->subqueues);
3171
			$pfq_rule .= " { ";
3172
			foreach ($this->subqueues as $qkey => $qnone) {
3173
				if ($i > 1) {
3174
					$i--;
3175
					$pfq_rule .= " {$qkey}, ";
3176 61e047a5 Phil Davis
				} else {
3177 f5881023 Ermal Lu?i
					$pfq_rule .= " {$qkey} ";
3178 61e047a5 Phil Davis
				}
3179 f5881023 Ermal Lu?i
			}
3180
			$pfq_rule .= " } \n";
3181 61e047a5 Phil Davis
			foreach ($this->subqueues as $q) {
3182 9d0b0635 Ermal
				$pfq_rule .= $q->build_rules($default);
3183 61e047a5 Phil Davis
			}
3184 f5881023 Ermal Lu?i
		}
3185 92125c97 Ermal Luçi
3186 f5881023 Ermal Lu?i
		$pfq_rule .= " \n";
3187
		return $pfq_rule;
3188 92125c97 Ermal Luçi
	}
3189
3190
	function build_form() {
3191 aef9d8fe Stephen Beaver
		$sform = parent::build_form();
3192 806942d0 Stephen Beaver
3193 9ce54773 Stephen Beaver
		$section = new Form_Section('NOTITLE');
3194 aef9d8fe Stephen Beaver
3195
		$group = new Form_Group('Bandwidth');
3196 806942d0 Stephen Beaver
3197 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
3198
			'bandwidth',
3199
			null,
3200
			'number',
3201
			$this->GetBandwidth()
3202
		));
3203 806942d0 Stephen Beaver
3204 aef9d8fe Stephen Beaver
		$group->add(new Form_Select(
3205
			'bandwidthtype',
3206
			null,
3207 9abbcb4b Viktor G
			$this->FormGetBwscale(),
3208 bfc94df0 Phil Davis
			array('Kb' => 'Kbit/s',
3209
				  'Mb' => 'Mbit/s',
3210
				  'Gb' => 'Gbit/s',
3211
				  'b' => 'Bit/s',
3212 820519e5 Stephen Beaver
				  '%' => '%')
3213 aef9d8fe Stephen Beaver
		));
3214 806942d0 Stephen Beaver
3215 aef9d8fe Stephen Beaver
		$group->setHelp('Choose the amount of bandwidth for this queue');
3216
3217
		$section->add($group);
3218 806942d0 Stephen Beaver
3219 aef9d8fe Stephen Beaver
		$section->addInput(new Form_Checkbox(
3220
			'borrow',
3221 9ddd492c Stephen Beaver
			'Scheduler option',
3222 aef9d8fe Stephen Beaver
			'Borrow from other queues when available',
3223
			($this->GetBorrow() == "on")
3224 806942d0 Stephen Beaver
		));
3225
3226 7bba13e8 Stephen Beaver
		$sform->add($section);
3227
3228 aef9d8fe Stephen Beaver
		return $sform;
3229 92125c97 Ermal Luçi
	}
3230 197bfe96 Ermal Luçi
3231 420b4538 Renato Botelho
	function update_altq_queue_data(&$data) {
3232 197bfe96 Ermal Luçi
		$this->ReadConfig($data);
3233
	}
3234 061f78b1 Bill Marquette
3235 92125c97 Ermal Luçi
	function wconfig() {
3236 197bfe96 Ermal Luçi
		$cflink =& get_reference_to_me_in_config($this->GetLink());
3237 61e047a5 Phil Davis
		if (!is_array($cflink)) {
3238 f5881023 Ermal Lu?i
			$cflink = array();
3239 61e047a5 Phil Davis
		}
3240 f5881023 Ermal Lu?i
		$cflink['interface'] = $this->GetInterface();
3241
		$cflink['qlimit'] = trim($this->GetQlimit());
3242 61e047a5 Phil Davis
		if (empty($cflink['qlimit'])) {
3243 f5881023 Ermal Lu?i
			unset($cflink['qlimit']);
3244 61e047a5 Phil Davis
		}
3245 f5881023 Ermal Lu?i
		$cflink['priority'] = $this->GetQpriority();
3246 41799195 PiBa-NL
		if (!is_numeric($cflink['priority'])) {
3247 f5881023 Ermal Lu?i
			unset($cflink['priority']);
3248 61e047a5 Phil Davis
		}
3249 f5881023 Ermal Lu?i
		$cflink['name'] = $this->GetQname();
3250
		$cflink['description'] = $this->GetDescription();
3251 61e047a5 Phil Davis
		if (empty($cflink['description'])) {
3252 f5881023 Ermal Lu?i
			unset($cflink['description']);
3253 61e047a5 Phil Davis
		}
3254 f5881023 Ermal Lu?i
		$cflink['bandwidth'] = $this->GetBandwidth();
3255
		$cflink['bandwidthtype'] = $this->GetBwscale();
3256
		$cflink['enabled'] = trim($this->GetEnabled());
3257 61e047a5 Phil Davis
		if (empty($cflink['enabled'])) {
3258 f5881023 Ermal Lu?i
			unset($cflink['enabled']);
3259 61e047a5 Phil Davis
		}
3260 f5881023 Ermal Lu?i
		$cflink['default'] = trim($this->GetDefault());
3261 61e047a5 Phil Davis
		if (empty($cflink['default'])) {
3262 f5881023 Ermal Lu?i
			unset($cflink['default']);
3263 61e047a5 Phil Davis
		}
3264 f5881023 Ermal Lu?i
		$cflink['red'] = trim($this->GetRed());
3265 61e047a5 Phil Davis
		if (empty($cflink['red'])) {
3266 f5881023 Ermal Lu?i
			unset($cflink['red']);
3267 61e047a5 Phil Davis
		}
3268 f5881023 Ermal Lu?i
		$cflink['rio'] = trim($this->GetRio());
3269 61e047a5 Phil Davis
		if (empty($cflink['rio'])) {
3270 f5881023 Ermal Lu?i
			unset($cflink['rio']);
3271 61e047a5 Phil Davis
		}
3272 f5881023 Ermal Lu?i
		$cflink['ecn'] = trim($this->GetEcn());
3273 61e047a5 Phil Davis
		if (empty($cflink['ecn'])) {
3274 f5881023 Ermal Lu?i
			unset($cflink['ecn']);
3275 61e047a5 Phil Davis
		}
3276 9f6919e6 Richard Connon
		$cflink['codel'] = trim($this->GetCodel());
3277 61e047a5 Phil Davis
		if (empty($cflink['codel'])) {
3278 9f6919e6 Richard Connon
			unset($cflink['codel']);
3279 61e047a5 Phil Davis
		}
3280 f5881023 Ermal Lu?i
		$cflink['borrow'] = trim($this->GetBorrow());
3281 61e047a5 Phil Davis
		if (empty($cflink['borrow'])) {
3282 f5881023 Ermal Lu?i
			unset($cflink['borrow']);
3283 61e047a5 Phil Davis
		}
3284 f5881023 Ermal Lu?i
	}
3285 197bfe96 Ermal Luçi
}
3286 061f78b1 Bill Marquette
3287 2b5caa0e Ermal Luçi
class fairq_queue extends priq_queue {
3288 f5881023 Ermal Lu?i
	var $hogs;
3289
	var $buckets;
3290 2b5caa0e Ermal Luçi
3291
	function GetBuckets() {
3292
		return $this->buckets;
3293
	}
3294
	function SetBuckets($buckets) {
3295 ae3d3adb Ermal Luçi
		$this->buckets = $buckets;
3296 2b5caa0e Ermal Luçi
	}
3297
	function GetHogs() {
3298
		return $this->hogs;
3299
	}
3300
	function SetHogs($hogs) {
3301 ae3d3adb Ermal Luçi
		$this->hogs = $hogs;
3302 2b5caa0e Ermal Luçi
	}
3303 70b139a3 Chris Buechler
	function CanHaveChildren() {
3304 2b5caa0e Ermal Luçi
		return false;
3305
	}
3306
3307
3308
	function copy_queue($interface, &$cflink) {
3309 420b4538 Renato Botelho
		$cflink['interface'] = $interface;
3310
		$cflink['qlimit'] = $this->GetQlimit();
3311
		$cflink['priority'] = $this->GetQpriority();
3312
		$cflink['name'] = $this->GetQname();
3313
		$cflink['description'] = $this->GetDescription();
3314
		$cflink['bandwidth'] = $this->GetBandwidth();
3315
		$cflink['bandwidthtype'] = $this->GetBwscale();
3316
		$cflink['enabled'] = $this->GetEnabled();
3317
		$cflink['default'] = $this->GetDefault();
3318
		$cflink['red'] = $this->GetRed();
3319
		$cflink['rio'] = $this->GetRio();
3320
		$cflink['ecn'] = $this->GetEcn();
3321
		$cflink['buckets'] = $this->GetBuckets();
3322 8774ca6e Ermal Luçi
		$cflink['hogs'] = $this->GetHogs();
3323 2b5caa0e Ermal Luçi
	}
3324 ce0117f7 Colin Fleming
3325 2b5caa0e Ermal Luçi
	/*
3326 70b139a3 Chris Buechler
	 * Should search even its children
3327 2b5caa0e Ermal Luçi
	 */
3328
	function &find_queue($interface, $qname) {
3329 61e047a5 Phil Davis
		if ($qname == $this->GetQname()) {
3330 2b5caa0e Ermal Luçi
			return $this;
3331 61e047a5 Phil Davis
		}
3332 2b5caa0e Ermal Luçi
	}
3333
3334 62150088 Ermal Lu?i
	function find_parentqueue($interface, $qname) { return; }
3335 2b5caa0e Ermal Luçi
3336
	function delete_queue() {
3337
		unref_on_altq_queue_list($this->GetQname());
3338
		cleanup_queue_from_rules($this->GetQname());
3339
		unset_object_by_reference($this->GetLink());
3340
	}
3341 ce0117f7 Colin Fleming
3342 2b5caa0e Ermal Luçi
	function validate_input($data, &$input_errors) {
3343
		parent::validate_input($data, $input_errors);
3344 ce0117f7 Colin Fleming
3345 41799195 PiBa-NL
		if ($data['priority'] > 7) {
3346
				$input_errors[] = gettext("Priority must be an integer between 0 and 7.");
3347 61e047a5 Phil Davis
		}
3348 2c072899 jim-p
		$reqdfields[] = "bandwidth";
3349 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidth");
3350 2c072899 jim-p
		$reqdfields[] = "bandwidthtype";
3351 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidthtype");
3352 2b5caa0e Ermal Luçi
3353
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
3354
	}
3355 ce0117f7 Colin Fleming
3356 2b5caa0e Ermal Luçi
	function ReadConfig(&$q) {
3357
		parent::ReadConfig($q);
3358 61e047a5 Phil Davis
		if (!empty($q['buckets'])) {
3359 2b5caa0e Ermal Luçi
			$this->SetBuckets($q['buckets']);
3360 61e047a5 Phil Davis
		} else {
3361 7ed9c6ac Ermal
			$this->SetBuckets("");
3362 61e047a5 Phil Davis
		}
3363
		if (!empty($q['hogs']) && is_valid_shaperbw($q['hogs'])) {
3364 2b5caa0e Ermal Luçi
			$this->SetHogs($q['hogs']);
3365 61e047a5 Phil Davis
		} else {
3366 7ed9c6ac Ermal
			$this->SetHogs("");
3367 61e047a5 Phil Davis
		}
3368 2b5caa0e Ermal Luçi
	}
3369 ce0117f7 Colin Fleming
3370 2b5caa0e Ermal Luçi
	function build_javascript() {
3371
		return parent::build_javascript();
3372
	}
3373
3374
	function build_tree() {
3375 420b4538 Renato Botelho
		$tree = " <li><a href=\"firewall_shaper.php?interface=" .
3376 1072b933 jim-p
		$this->GetInterface()."&amp;queue=" . htmlspecialchars($this->GetQname())."&amp;action=show";
3377 f5881023 Ermal Lu?i
		$tree .= "\" ";
3378
		$tmpvalue = trim($this->GetDefault());
3379 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
3380 f5881023 Ermal Lu?i
			$tree .= " class=\"navlnk\"";
3381 61e047a5 Phil Davis
		}
3382 1072b933 jim-p
		$tree .= " >" . htmlspecialchars($this->GetQname()) . "</a>";
3383 f5881023 Ermal Lu?i
		$tree .= "</li>";
3384
		return $tree;
3385 2b5caa0e Ermal Luçi
	}
3386 ce0117f7 Colin Fleming
3387 70b139a3 Chris Buechler
	/* Even this should take children into consideration */
3388 9d0b0635 Ermal
	function build_rules(&$default = false) {
3389 2b5caa0e Ermal Luçi
		$pfq_rule = "queue ". $this->qname;
3390 61e047a5 Phil Davis
		if ($this->GetInterface()) {
3391 85a5da13 Ermal Luçi
			$pfq_rule .= " on ".get_real_interface($this->GetInterface());
3392 61e047a5 Phil Davis
		}
3393
		if ($this->GetBandwidth() && $this->GetBwscale()) {
3394 2b5caa0e Ermal Luçi
			$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
3395 61e047a5 Phil Davis
		}
3396 f5881023 Ermal Lu?i
		$tmpvalue = trim($this->GetQpriority());
3397 41799195 PiBa-NL
		if (is_numeric($tmpvalue)) {
3398 2b5caa0e Ermal Luçi
			$pfq_rule .= " priority " . $this->GetQpriority();
3399 61e047a5 Phil Davis
		}
3400 f5881023 Ermal Lu?i
		$tmpvalue = trim($this->GetQlimit());
3401 61e047a5 Phil Davis
		if (!empty($tmpvalue)) {
3402 2b5caa0e Ermal Luçi
			$pfq_rule .= " qlimit " . $this->GetQlimit();
3403 61e047a5 Phil Davis
		}
3404
		if ($this->GetDefault() || $this->GetRed() || $this->GetRio() ||
3405 4de8f7ba Phil Davis
		    $this->GetEcn() || $this->GetBuckets() || $this->GetHogs() || $this->GetCodel()) {
3406 ae3d3adb Ermal Luçi
			$pfq_rule .= " fairq ( ";
3407 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetRed());
3408
			if (!empty($tmpvalue)) {
3409 2b5caa0e Ermal Luçi
				$comma = 1;
3410
				$pfq_rule .= " red ";
3411
			}
3412 8edaa92c Ermal
			$tmpvalue = trim($this->GetCodel());
3413
			if (!empty($tmpvalue)) {
3414
				$comma = 1;
3415
				$pfq_rule .= " codel ";
3416
			}
3417 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetRio());
3418
			if (!empty($tmpvalue)) {
3419 61e047a5 Phil Davis
				if ($comma) {
3420 2b5caa0e Ermal Luçi
					$pfq_rule .= " ,";
3421 61e047a5 Phil Davis
				}
3422 2b5caa0e Ermal Luçi
				$comma = 1;
3423
				$pfq_rule .= " rio ";
3424
			}
3425 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetEcn());
3426
			if (!empty($tmpvalue)) {
3427 61e047a5 Phil Davis
				if ($comma) {
3428 2b5caa0e Ermal Luçi
					$pfq_rule .= " ,";
3429 61e047a5 Phil Davis
				}
3430 2b5caa0e Ermal Luçi
				$comma = 1;
3431
				$pfq_rule .= " ecn ";
3432
			}
3433 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetDefault());
3434
			if (!empty($tmpvalue)) {
3435 61e047a5 Phil Davis
				if ($comma) {
3436 2b5caa0e Ermal Luçi
					$pfq_rule .= " ,";
3437 61e047a5 Phil Davis
				}
3438 2b5caa0e Ermal Luçi
				$comma = 1;
3439
				$pfq_rule .= " default ";
3440 ef8fca71 Ermal
				$default = true;
3441 2b5caa0e Ermal Luçi
			}
3442 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetBuckets());
3443
			if (!empty($tmpvalue)) {
3444 61e047a5 Phil Davis
				if ($comma) {
3445 2b5caa0e Ermal Luçi
					$pfq_rule .= ", ";
3446 61e047a5 Phil Davis
				}
3447 2b5caa0e Ermal Luçi
				$pfq_rule .= " buckets " . $this->GetBuckets() . " ";
3448
			}
3449 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetHogs());
3450
			if (!empty($tmpvalue)) {
3451 61e047a5 Phil Davis
				if ($comma) {
3452 2b5caa0e Ermal Luçi
					$pfq_rule .= ", ";
3453 61e047a5 Phil Davis
				}
3454 2b5caa0e Ermal Luçi
				$pfq_rule .= " hogs " . $this->GetHogs() . " ";
3455
			}
3456 61e047a5 Phil Davis
			$pfq_rule .= " ) ";
3457 420b4538 Renato Botelho
		}
3458 2b5caa0e Ermal Luçi
3459
		$pfq_rule .= " \n";
3460
		return $pfq_rule;
3461
	}
3462
3463
	function build_form() {
3464 f5e511d3 Ermal
		$form = parent::build_form();
3465 806942d0 Stephen Beaver
3466 aef9d8fe Stephen Beaver
		$section = new Form_Section('');
3467
3468
		$group = new Form_Group('Bandwidth');
3469 806942d0 Stephen Beaver
3470 aef9d8fe Stephen Beaver
		$group->add(new Form_Input(
3471
			'bandwidth',
3472
			null,
3473
			'number',
3474
			$this->GetBandwidth()
3475
		));
3476 806942d0 Stephen Beaver
3477 aef9d8fe Stephen Beaver
		$group->add(new Form_Select(
3478
			'bandwidthtype',
3479
			null,
3480 9abbcb4b Viktor G
			$this->FormGetBwscale(),
3481 bfc94df0 Phil Davis
			array('Kb' => 'Kbit/s',
3482
				  'Mb' => 'Mbit/s',
3483
				  'Gb' => 'Gbit/s',
3484
				  'b' => 'Bit/s',
3485 820519e5 Stephen Beaver
				  '%' => '%')
3486 aef9d8fe Stephen Beaver
		));
3487 806942d0 Stephen Beaver
3488 aef9d8fe Stephen Beaver
		$group->setHelp('Choose the amount of bandwidth for this queue');
3489
3490
		$section->add($group);
3491 806942d0 Stephen Beaver
3492 43568d7d Stephen Beaver
		$section->addInput(new Form_Input(
3493
			'buckets',
3494
			'Scheduler specific options',
3495
			'text',
3496
			$this->GetBuckets()
3497
		))->setHelp('Number of buckets available');
3498 aef9d8fe Stephen Beaver
3499 4700a731 Stephen Beaver
		$section->addInput(new Form_Input(
3500 43568d7d Stephen Beaver
			'hogs',
3501
			'',
3502
			'text',
3503
			$this->GetHogs()
3504
			))->setHelp('Bandwidth limit for hosts to not saturate link');
3505
3506
		$form->add($section);
3507 2b5caa0e Ermal Luçi
		return $form;
3508
	}
3509
3510 420b4538 Renato Botelho
	function update_altq_queue_data(&$data) {
3511 2b5caa0e Ermal Luçi
		$this->ReadConfig($data);
3512
	}
3513
3514
	function wconfig() {
3515
		$cflink =& get_reference_to_me_in_config($this->GetLink());
3516 61e047a5 Phil Davis
		if (!is_array($cflink)) {
3517 2b5caa0e Ermal Luçi
			$cflink = array();
3518 61e047a5 Phil Davis
		}
3519 2b5caa0e Ermal Luçi
		$cflink['interface'] = $this->GetInterface();
3520 f5881023 Ermal Lu?i
		$cflink['qlimit'] = trim($this->GetQlimit());
3521 61e047a5 Phil Davis
		if (empty($cflink['qlimit'])) {
3522 f5881023 Ermal Lu?i
			unset($cflink['qlimit']);
3523 61e047a5 Phil Davis
		}
3524 f5881023 Ermal Lu?i
		$cflink['priority'] = trim($this->GetQpriority());
3525 41799195 PiBa-NL
		if (!is_numeric($cflink['priority'])) {
3526 f5881023 Ermal Lu?i
			unset($cflink['priority']);
3527 61e047a5 Phil Davis
		}
3528 2b5caa0e Ermal Luçi
		$cflink['name'] = $this->GetQname();
3529 f5881023 Ermal Lu?i
		$cflink['description'] = trim($this->GetDescription());
3530 61e047a5 Phil Davis
		if (empty($cflink['description'])) {
3531 f5881023 Ermal Lu?i
			unset($cflink['description']);
3532 61e047a5 Phil Davis
		}
3533 2b5caa0e Ermal Luçi
		$cflink['bandwidth'] = $this->GetBandwidth();
3534
		$cflink['bandwidthtype'] = $this->GetBwscale();
3535
		$cflink['enabled'] = $this->GetEnabled();
3536 61e047a5 Phil Davis
		if (empty($cflink['enabled'])) {
3537 f5881023 Ermal Lu?i
			unset($cflink['enabled']);
3538 61e047a5 Phil Davis
		}
3539 f5881023 Ermal Lu?i
		$cflink['default'] = trim($this->GetDefault());
3540 61e047a5 Phil Davis
		if (empty($cflink['default'])) {
3541 f5881023 Ermal Lu?i
			unset($cflink['default']);
3542 61e047a5 Phil Davis
		}
3543 f5881023 Ermal Lu?i
		$cflink['red'] = trim($this->GetRed());
3544 61e047a5 Phil Davis
		if (empty($cflink['red'])) {
3545 f5881023 Ermal Lu?i
			unset($cflink['red']);
3546 61e047a5 Phil Davis
		}
3547 f5881023 Ermal Lu?i
		$cflink['rio'] = trim($this->GetRio());
3548 61e047a5 Phil Davis
		if (empty($cflink['rio'])) {
3549 f5881023 Ermal Lu?i
			unset($cflink['rio']);
3550 61e047a5 Phil Davis
		}
3551 f5881023 Ermal Lu?i
		$cflink['ecn'] = trim($this->GetEcn());
3552 61e047a5 Phil Davis
		if (empty($cflink['ecn'])) {
3553 f5881023 Ermal Lu?i
			unset($cflink['ecn']);
3554 61e047a5 Phil Davis
		}
3555 9f6919e6 Richard Connon
		$cflink['codel'] = trim($this->GetCodel());
3556 61e047a5 Phil Davis
		if (empty($cflink['codel'])) {
3557 9f6919e6 Richard Connon
			unset($cflink['codel']);
3558 61e047a5 Phil Davis
		}
3559 f5881023 Ermal Lu?i
		$cflink['buckets'] = trim($this->GetBuckets());
3560 61e047a5 Phil Davis
		if (empty($cflink['buckets'])) {
3561 f5881023 Ermal Lu?i
			unset($cflink['buckets']);
3562 61e047a5 Phil Davis
		}
3563 f5881023 Ermal Lu?i
		$cflink['hogs'] = trim($this->GetHogs());
3564 61e047a5 Phil Davis
		if (empty($cflink['hogs'])) {
3565 f5881023 Ermal Lu?i
			unset($cflink['hogs']);
3566 61e047a5 Phil Davis
		}
3567 2b5caa0e Ermal Luçi
	}
3568
}
3569 061f78b1 Bill Marquette
3570
3571 c25a6b6a Ermal Luçi
/*
3572 0dc7b4aa Ermal
 * dummynet(4) wrappers.
3573 c25a6b6a Ermal Luçi
 */
3574
3575
3576
/*
3577
 * List of respective objects!
3578
 */
3579 d62ba478 Ermal Luçi
$dummynet_pipe_list = array();
3580 c25a6b6a Ermal Luçi
3581
class dummynet_class {
3582 420b4538 Renato Botelho
	var $qname;
3583 f5881023 Ermal Lu?i
	var $qnumber; /* dummynet(4) uses numbers instead of names; maybe integrate with pf the same as altq does?! */
3584 420b4538 Renato Botelho
	var $qlimit;
3585
	var $description;
3586 f5881023 Ermal Lu?i
	var $qenabled;
3587
	var $link;
3588
	var $qparent; /* link to upper class so we do things easily on WF2Q+ rule creation */
3589 420b4538 Renato Botelho
	var $plr;
3590
3591
	var $buckets;
3592
	/* mask parameters */
3593
	var $mask;
3594
	var $noerror;
3595
3596
	/* Accessor functions */
3597
	function SetLink($link) {
3598
		$this->link = $link;
3599
	}
3600
	function GetLink() {
3601
		return $this->link;
3602
	}
3603 0b4e7542 Jean Cyr
	function GetMask() {
3604 61e047a5 Phil Davis
		if (!isset($this->mask["type"])) {
3605 8c50a9d8 Jean Cyr
			$this->mask["type"] = "none";
3606 61e047a5 Phil Davis
		}
3607 f5881023 Ermal Lu?i
		return $this->mask;
3608
	}
3609
	function SetMask($mask) {
3610
		$this->mask = $mask;
3611
	}
3612
	function &GetParent() {
3613
		return $this->qparent;
3614
	}
3615
	function SetParent(&$parent) {
3616
		$this->qparent = &$parent;
3617
	}
3618 420b4538 Renato Botelho
	function GetEnabled() {
3619
		return $this->qenabled;
3620
	}
3621
	function SetEnabled($value) {
3622
		$this->qenabled = $value;
3623
	}
3624 f5881023 Ermal Lu?i
	function CanHaveChildren() {
3625
		return false;
3626 420b4538 Renato Botelho
	}
3627 f5881023 Ermal Lu?i
	function CanBeDeleted() {
3628 420b4538 Renato Botelho
		return true;
3629
	}
3630
	function GetQname() {
3631
		return $this->qname;
3632
	}
3633
	function SetQname($name) {
3634
		$this->qname = trim($name);
3635
	}
3636
	function GetQlimit() {
3637
		return $this->qlimit;
3638
	}
3639
	function SetQlimit($limit) {
3640
		$this->qlimit = $limit;
3641
	}
3642
	function GetDescription() {
3643
		return $this->description;
3644
	}
3645
	function SetDescription($str) {
3646
		$this->description = trim($str);
3647
	}
3648
	function GetFirstime() {
3649
		return $this->firsttime;
3650
	}
3651
	function SetFirsttime($number) {
3652
		$this->firsttime = $number;
3653
	}
3654
	function GetBuckets() {
3655
		return $this->buckets;
3656
	}
3657
	function SetBuckets($buckets) {
3658
		$this->buckets = $buckets;
3659
	}
3660 f5881023 Ermal Lu?i
	function SetNumber($number) {
3661
		$this->qnumber = $number;
3662
	}
3663
	function GetNumber() {
3664
		return $this->qnumber;
3665
	}
3666 420b4538 Renato Botelho
	function GetPlr() {
3667
		return $this->plr;
3668
	}
3669
	function SetPlr($plr) {
3670
		$this->plr = $plr;
3671
	}
3672 c25a6b6a Ermal Luçi
3673 8c50a9d8 Jean Cyr
	function build_javascript() {
3674 2d46e1e4 Jean Cyr
		$javascript .= "<script type=\"text/javascript\">\n";
3675 8c50a9d8 Jean Cyr
		$javascript .= "//<![CDATA[\n";
3676 2d46e1e4 Jean Cyr
		$javascript .= "function enable_maskbits(enable_over) {\n";
3677
		$javascript .= "var e = document.getElementById(\"mask\");\n";
3678
		$javascript .= "if ((e.options[e.selectedIndex].text == \"none\") || enable_over) {\n";
3679 8c50a9d8 Jean Cyr
		$javascript .= "document.iform.maskbits.disabled = 1;\n";
3680
		$javascript .= "document.iform.maskbits.value = \"\";\n";
3681 853030ac Jean Cyr
		$javascript .= "document.iform.maskbitsv6.disabled = 1;\n";
3682
		$javascript .= "document.iform.maskbitsv6.value = \"\";\n";
3683 2d46e1e4 Jean Cyr
		$javascript .= "} else {\n";
3684 8c50a9d8 Jean Cyr
		$javascript .= "document.iform.maskbits.disabled = 0;\n";
3685 420b4538 Renato Botelho
		$javascript .= "document.iform.maskbitsv6.disabled = 0;\n";
3686 2d46e1e4 Jean Cyr
		$javascript .= "}}\n";
3687 8c50a9d8 Jean Cyr
		$javascript .= "//]]>\n";
3688 2d46e1e4 Jean Cyr
		$javascript .= "</script>\n";
3689 8c50a9d8 Jean Cyr
		return $javascript;
3690
	}
3691 d62ba478 Ermal Luçi
3692 f5881023 Ermal Lu?i
	function validate_input($data, &$input_errors) {
3693
		$reqdfields[] = "bandwidth";
3694 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidth");
3695 5274102e Chris Buechler
		/*$reqdfields[] = "burst";
3696
		$reqdfieldsn[] = gettext("Burst"); */
3697 f5881023 Ermal Lu?i
		$reqdfields[] = "bandwidthtype";
3698 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidthtype");
3699 6be14e38 Ermal
		$reqdfields[] = "newname";
3700 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Name");
3701 ce0117f7 Colin Fleming
3702 f5881023 Ermal Lu?i
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
3703
3704 0f0f7b2c Renato Botelho
		if ($data['plr'] && (!is_numeric($data['plr']) ||
3705 4de8f7ba Phil Davis
		    ($data['plr'] < 0) || ($data['plr'] > 1))) {
3706 cabb34e4 Chris Buechler
			$input_errors[] = gettext("Packet Loss Rate must be a value between 0 and 1.");
3707 61e047a5 Phil Davis
		}
3708 0f0f7b2c Renato Botelho
		if ($data['buckets'] && (!is_numeric($data['buckets']) ||
3709 4de8f7ba Phil Davis
		    ($data['buckets'] < 16) || ($data['buckets'] > 65535))) {
3710
			$input_errors[] = gettext("Buckets must be an integer between 16 and 65535.");
3711 61e047a5 Phil Davis
		}
3712
		if ($data['qlimit'] && (!is_numeric($data['qlimit']))) {
3713 420b4538 Renato Botelho
			$input_errors[] = gettext("Queue limit must be an integer");
3714 61e047a5 Phil Davis
		}
3715
		if (!empty($data['newname']) && !preg_match("/^[a-zA-Z0-9_-]+$/", $data['newname'])) {
3716 152ab4d0 Vinicius Coque
			$input_errors[] = gettext("Queue names must be alphanumeric and _ or - only.");
3717 61e047a5 Phil Davis
		}
3718
		if (!empty($data['name']) && !preg_match("/^[a-zA-Z0-9_-]+$/", $data['name'])) {
3719 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("Queue names must be alphanumeric and _ or - only.");
3720 61e047a5 Phil Davis
		}
3721
		if (isset($data['maskbits']) && ($data['maskbits'] <> "")) {
3722
			if ((!is_numeric($data['maskbits'])) || ($data['maskbits'] <= 0) || ($data['maskbits'] > 32)) {
3723 cabb34e4 Chris Buechler
				$input_errors[] = gettext("IPv4 bit mask must be blank or numeric value between 1 and 32.");
3724 61e047a5 Phil Davis
			}
3725
		}
3726
		if (isset($data['maskbitsv6']) && ($data['maskbitsv6'] <> "")) {
3727
			if ((!is_numeric($data['maskbitsv6'])) || ($data['maskbitsv6'] <= 0) || ($data['maskbitsv6'] > 128)) {
3728 cabb34e4 Chris Buechler
				$input_errors[] = gettext("IPv6 bit mask must be blank or numeric value between 1 and 128.");
3729 61e047a5 Phil Davis
			}
3730
		}
3731 2d46e1e4 Jean Cyr
	}
3732 420b4538 Renato Botelho
3733 2d46e1e4 Jean Cyr
	function build_mask_rules(&$pfq_rule) {
3734
		$mask = $this->GetMask();
3735
		if (!empty($mask['type'])) {
3736 61e047a5 Phil Davis
			if ($mask['type'] <> 'none') {
3737 2d46e1e4 Jean Cyr
				$pfq_rule .= " mask";
3738 61e047a5 Phil Davis
			}
3739 2d46e1e4 Jean Cyr
			switch ($mask['type']) {
3740 61e047a5 Phil Davis
				case 'srcaddress':
3741
					if (!empty($mask['bitsv6']) && ($mask['bitsv6'] <> "")) {
3742
						$pfq_rule .= " src-ip6 /" . $mask['bitsv6'];
3743
					} else {
3744
						$pfq_rule .= " src-ip6 /128";
3745
					}
3746
					if (!empty($mask['bits']) && ($mask['bits'] <> "")) {
3747
						$pfq_rule .= sprintf(" src-ip 0x%x", gen_subnet_mask_long($mask['bits']));
3748
					} else {
3749
						$pfq_rule .= " src-ip 0xffffffff";
3750
					}
3751
					break;
3752
				case 'dstaddress':
3753
					if (!empty($mask['bitsv6']) && ($mask['bitsv6'] <> "")) {
3754
						$pfq_rule .= " dst-ip6 /" . $mask['bitsv6'];
3755
					} else {
3756
						$pfq_rule .= " dst-ip6 /128";
3757
					}
3758
					if (!empty($mask['bits']) && ($mask['bits'] <> "")) {
3759
						$pfq_rule .= sprintf(" dst-ip 0x%x", gen_subnet_mask_long($mask['bits']));
3760
					} else {
3761
						$pfq_rule .= " dst-ip 0xffffffff";
3762
					}
3763
					break;
3764
				default:
3765
					break;
3766 2d46e1e4 Jean Cyr
			}
3767 420b4538 Renato Botelho
		}
3768 f5881023 Ermal Lu?i
	}
3769 420b4538 Renato Botelho
3770 c25a6b6a Ermal Luçi
}
3771
3772
class dnpipe_class extends dummynet_class {
3773 420b4538 Renato Botelho
	var $delay;
3774 c9ba2f8a Ermal
	var $qbandwidth = array();
3775 d62ba478 Ermal Luçi
	var $qbandwidthtype;
3776 d4f29a52 Steve Beaver
3777 254581a5 Matt Underscore
	/* Limiter queue patch */
3778 402012d9 Viktor G
	var $ecn; // ecn 'on' or 'off'
3779 10006140 Harley Peters
	var $pie_onoff;
3780
	var $pie_capdrop;
3781
	var $pie_qdelay;
3782
	var $pie_pderand;
3783 402012d9 Viktor G
	var $aqm; // key to aqm_map
3784
	var $aqm_params = array(); // AQM params
3785
	var $scheduler;	// key to scheduler_map
3786
	var $scheduler_params = array(); // AQM params
3787 254581a5 Matt Underscore
	function GetAQM() {
3788
			return $this->aqm;
3789
	}
3790
	function SetAQM($aqm) {
3791
			$this->aqm = $aqm;
3792
	}
3793
	function GetAQMParameters() {
3794
			return $this->aqm_params;
3795
	}
3796 50d4c4f2 Matt Underscore
	function GetAQMParameter($parameter) {
3797
			return $this->aqm_params[$parameter];
3798
	}
3799
	function SetAQMParameter($key, $value) {
3800
			return $this->aqm_params[$key] = $value;
3801
	}
3802 254581a5 Matt Underscore
	function SetAQMParameters($params) {
3803
			$this->aqm_params = $params;
3804
	}
3805
	function GetECN() {
3806
			return $this->ecn;
3807
	}
3808
	function SetECN($ecn) {
3809
			$this->ecn = $ecn;
3810
	}
3811 10006140 Harley Peters
	function GetPIE_ONOFF() {
3812
			return $this->pie_onoff;
3813
	}
3814
	function SetPIE_ONOFF($pie_onoff) {
3815
			$this->pie_onoff = $pie_onoff;
3816
	}
3817
	function GetPIE_CAPDROP() {
3818
			return $this->pie_capdrop;
3819
	}
3820
	function SetPIE_CAPDROP($pie_capdrop) {
3821
			$this->pie_capdrop = $pie_capdrop;
3822
	}
3823
	function GetPIE_QDELAY() {
3824
			return $this->pie_qdelay;
3825
	}
3826
	function SetPIE_QDELAY($pie_qdelay) {
3827
			$this->pie_qdelay = $pie_qdelay;
3828
	}
3829
	function GetPIE_PDERAND() {
3830
			return $this->pie_pderand;
3831
	}
3832
	function SetPIE_PDERAND($pie_pderand) {
3833
			$this->pie_pderand = $pie_pderand;
3834
	}
3835 254581a5 Matt Underscore
	function GetScheduler() {
3836
			return $this->scheduler;
3837
	}
3838
	function SetScheduler($scheduler) {
3839
			$this->scheduler = $scheduler;
3840
	}
3841
	function GetSchedulerParameters() {
3842
			return $this->scheduler_params;
3843
	}
3844
	function SetSchedulerParameters($params) {
3845
			$this->scheduler_params = $params;
3846
	}
3847 50d4c4f2 Matt Underscore
	function SetSchedulerParameter($key, $value) {
3848
			$this->scheduler_params[$key] = $value;
3849
	}
3850
	function GetSchedulerParameter($key) {
3851
			return $this->scheduler_params[$key];
3852
	}
3853 254581a5 Matt Underscore
	/* End limiter queue patch */
3854 c25a6b6a Ermal Luçi
3855
		/* This is here to help on form building and building rules/lists */
3856 420b4538 Renato Botelho
	var $subqueues = array();
3857 c25a6b6a Ermal Luçi
3858 70b139a3 Chris Buechler
	function CanHaveChildren() {
3859 420b4538 Renato Botelho
		return true;
3860
	}
3861 d62ba478 Ermal Luçi
	function SetDelay($delay) {
3862
		$this->delay = $delay;
3863
	}
3864
	function GetDelay() {
3865
		return $this->delay;
3866
	}
3867
	function delete_queue() {
3868
		cleanup_dnqueue_from_rules($this->GetQname());
3869 61e047a5 Phil Davis
		foreach ($this->subqueues as $q) {
3870 d62ba478 Ermal Luçi
			$q->delete_queue();
3871 61e047a5 Phil Davis
		}
3872 d62ba478 Ermal Luçi
		unset_dn_object_by_reference($this->GetLink());
3873 795e6194 Viktor G
		mwexec("/sbin/dnctl pipe delete " . $this->GetNumber());
3874
		mwexec("/sbin/dnctl sched delete " . $this->GetNumber());
3875 420b4538 Renato Botelho
	}
3876
	function GetBandwidth() {
3877
		return $this->qbandwidth;
3878
	}
3879
	function SetBandwidth($bandwidth) {
3880
		$this->qbandwidth = $bandwidth;
3881
	}
3882 61e047a5 Phil Davis
	function GetBurst() {
3883
		return $this->qburst;
3884
	}
3885
	function SetBurst($burst) {
3886
		$this->qburst = $burst;
3887
	}
3888 c25a6b6a Ermal Luçi
3889 d62ba478 Ermal Luçi
	function &add_queue($interface, &$queue, &$path, &$input_errors) {
3890 c25a6b6a Ermal Luçi
3891 61e047a5 Phil Davis
		if (!is_array($this->subqueues)) {
3892 d62ba478 Ermal Luçi
			$this->subqueues = array();
3893 61e047a5 Phil Davis
		}
3894 ce0117f7 Colin Fleming
3895 5c4fcabc Renato Botelho
		$__tmp_q = new dnqueue_class(); $q =& $__tmp_q;
3896 d62ba478 Ermal Luçi
		$q->SetLink($path);
3897
		$q->SetEnabled("on");
3898
		$q->SetPipe($this->GetQname());
3899 ea51e9f8 Renato Botelho
		$q->SetParent($this);
3900 d62ba478 Ermal Luçi
		$q->ReadConfig($queue);
3901
		$q->validate_input($queue, $input_errors);
3902 b2383d46 Steve Beaver
3903
		if (!is_array($input_errors)) {
3904
			$input_errors = array();
3905
		}
3906
3907 00ca3fb1 Ermal
		if (count($input_errors)) {
3908 c3ebf347 NOYB
			log_error(sprintf(gettext('SHAPER: Could not create queue %1$s on interface %2$s because: %3$s'), $q->GetQname(), $interface, print_r($input_errors, true)));
3909 d62ba478 Ermal Luçi
			return $q;
3910 00ca3fb1 Ermal
		}
3911 85a236e9 Ermal
		$number = dnqueue_find_nextnumber();
3912
		$q->SetNumber($number);
3913 d62ba478 Ermal Luçi
		$this->subqueues[$q->GetQname()] = &$q;
3914 420b4538 Renato Botelho
3915 d62ba478 Ermal Luçi
		return $q;
3916
	}
3917 c25a6b6a Ermal Luçi
3918 ea51e9f8 Renato Botelho
	function &get_queue_list(&$q = null) {
3919 d62ba478 Ermal Luçi
		$qlist = array();
3920 c25a6b6a Ermal Luçi
3921 64c7753b Ermal Luçi
		$qlist[$this->GetQname()] = $this->GetNumber();
3922 d62ba478 Ermal Luçi
		if (is_array($this->subqueues)) {
3923 61e047a5 Phil Davis
			foreach ($this->subqueues as $queue) {
3924 ea51e9f8 Renato Botelho
				$queue->get_queue_list($qlist);
3925 61e047a5 Phil Davis
			}
3926 c25a6b6a Ermal Luçi
		}
3927 d62ba478 Ermal Luçi
		return $qlist;
3928
	}
3929 ce0117f7 Colin Fleming
3930 420b4538 Renato Botelho
	/*
3931
	 * Should search even its children
3932
	 */
3933
	function &find_queue($pipe, $qname) {
3934 61e047a5 Phil Davis
		if ($qname == $this->GetQname()) {
3935 420b4538 Renato Botelho
			return $this;
3936 61e047a5 Phil Davis
		}
3937 420b4538 Renato Botelho
		foreach ($this->subqueues as $q) {
3938
			$result =& $q->find_queue("", $qname);
3939 61e047a5 Phil Davis
			if ($result) {
3940 420b4538 Renato Botelho
				return $result;
3941 61e047a5 Phil Davis
			}
3942 420b4538 Renato Botelho
		}
3943
	}
3944 c25a6b6a Ermal Luçi
3945 d62ba478 Ermal Luçi
	function &find_parentqueue($pipe, $qname) {
3946
		return NULL;
3947 420b4538 Renato Botelho
	}
3948 c25a6b6a Ermal Luçi
3949 d62ba478 Ermal Luçi
	function validate_input($data, &$input_errors) {
3950
		parent::validate_input($data, $input_errors);
3951 c25a6b6a Ermal Luçi
3952 c9ba2f8a Ermal
		$schedule = 0;
3953
		$schedulenone = 0;
3954
		$entries = 0;
3955 e02ea742 Ermal
		/* XXX: Really no better way? */
3956
		for ($i = 0; $i < 2900; $i++) {
3957 c9ba2f8a Ermal
			if (!empty($data["bwsched{$i}"])) {
3958 61e047a5 Phil Davis
				if ($data["bwsched{$i}"] != "none") {
3959 c9ba2f8a Ermal
					$schedule++;
3960 61e047a5 Phil Davis
				} else {
3961 c9ba2f8a Ermal
					$schedulenone++;
3962 61e047a5 Phil Davis
				}
3963 c9ba2f8a Ermal
			}
3964
			if (!empty($data["bandwidth{$i}"])) {
3965 61e047a5 Phil Davis
				if (!is_numeric($data["bandwidth{$i}"])) {
3966 c9ba2f8a Ermal
					$input_errors[] = sprintf(gettext("Bandwidth for schedule %s must be an integer."), $data["bwsched{$i}"]);
3967 61e047a5 Phil Davis
				} else if (($data["burst{$i}"] != "") && (!is_numeric($data["burst{$i}"]))) {
3968 794195d1 Phil Davis
					$input_errors[] = sprintf(gettext("Burst for schedule %s must be an integer."), $data["bwsched{$i}"]);
3969 61e047a5 Phil Davis
				} else {
3970 c9ba2f8a Ermal
					$entries++;
3971 61e047a5 Phil Davis
				}
3972 c9ba2f8a Ermal
			}
3973
		}
3974 61e047a5 Phil Davis
		if ($schedule == 0 && $entries > 1) {
3975 c3ebf347 NOYB
			$input_errors[] = gettext("A schedule needs to be specified for every additional entry.");
3976 61e047a5 Phil Davis
		}
3977
		if ($schedulenone > 0 && $entries > 1) {
3978 c3ebf347 NOYB
			$input_errors[] = gettext("If more than one bandwidth configured all schedules need to be selected.");
3979 61e047a5 Phil Davis
		}
3980
		if ($entries == 0) {
3981 c3ebf347 NOYB
			$input_errors[] = gettext("At least one bw specification is necessary.");
3982 61e047a5 Phil Davis
		}
3983
		if ($data['delay'] && (!is_numeric($data['delay']))) {
3984 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("Delay must be an integer.");
3985 61e047a5 Phil Davis
		}
3986 8afa74bb jim-p
		if ($data['delay'] && is_numeric($data['delay']) &&
3987
		    (($data['delay'] < 0) || ($data['delay'] > 10000))) {
3988
			$input_errors[] = gettext("Delay must be an integer between 0 and 10000.");
3989
		}
3990 d4f29a52 Steve Beaver
3991 254581a5 Matt Underscore
		/* Limiter patch */
3992
		$selectedScheduler = getSchedulers()[$data['sched']];
3993 202411c3 no
		if (!$selectedScheduler) {
3994
			$input_errors[] = gettext("Selected scheduler not recognized.");
3995
		}
3996 254581a5 Matt Underscore
		$selectedAqm = getAQMs()[$data['aqm']];
3997 cd3cde52 jim-p
		if (!empty($data['aqm']) && !$selectedAqm) {
3998 202411c3 no
			$input_errors[] = gettext("Selected AQM not recognized.");
3999
		}
4000 254581a5 Matt Underscore
		/* End limiter patch */
4001 dbaf21d4 Renato Botelho
	}
4002 c25a6b6a Ermal Luçi
4003 d62ba478 Ermal Luçi
	function ReadConfig(&$q) {
4004 1cbe86f0 Ermal
		if (!empty($q['name']) && !empty($q['newname']) && $q['name'] != $q['newname']) {
4005
			$this->SetQname($q['newname']);
4006 402012d9 Viktor G
			rename_dnqueue_in_rules($q['name'], $q['newname']);
4007 1cbe86f0 Ermal
		} else if (!empty($q['newname'])) {
4008
			$this->SetQname($q['newname']);
4009
		} else {
4010
			$this->SetQname($q['name']);
4011
		}
4012 d62ba478 Ermal Luçi
		$this->SetNumber($q['number']);
4013 c9ba2f8a Ermal
4014
		if (!empty($_POST)) {
4015
			$bandwidth = array();
4016 e02ea742 Ermal
			/* XXX: Really no better way? */
4017
			for ($i = 0; $i < 2900; $i++) {
4018 420b4538 Renato Botelho
				if (isset($q["bandwidth{$i}"]) && $q["bandwidth{$i}"] <> "") {
4019 c9ba2f8a Ermal
					$bw = array();
4020
					$bw['bw'] = $q["bandwidth{$i}"];
4021 4981f881 Ermal
					$bw['burst'] = $q["burst{$i}"];
4022 61e047a5 Phil Davis
					if (isset($q["bwtype{$i}"]) && $q["bwtype{$i}"]) {
4023 c9ba2f8a Ermal
						$bw['bwscale'] = $q["bwtype{$i}"];
4024 61e047a5 Phil Davis
					}
4025
					if (isset($q["bwsched{$i}"]) && $q["bwsched{$i}"]) {
4026 c9ba2f8a Ermal
						$bw['bwsched'] = $q["bwsched{$i}"];
4027 61e047a5 Phil Davis
					}
4028 c9ba2f8a Ermal
					$bandwidth[] = $bw;
4029
				}
4030
			}
4031
			$this->SetBandwidth($bandwidth);
4032 d62ba478 Ermal Luçi
		}
4033 420b4538 Renato Botelho
4034 4981f881 Ermal
		if (is_array($q['bandwidth']) && is_array($q['bandwidth']['item'])) {
4035 c9ba2f8a Ermal
			$this->SetBandwidth($q['bandwidth']['item']);
4036 4981f881 Ermal
			$this->SetBurst($q['burst']['item']);
4037
		}
4038 420b4538 Renato Botelho
4039 61e047a5 Phil Davis
		if (isset($q['qlimit']) && $q['qlimit'] <> "") {
4040 420b4538 Renato Botelho
			$this->SetQlimit($q['qlimit']);
4041 61e047a5 Phil Davis
		} else {
4042 420b4538 Renato Botelho
			$this->SetQlimit("");
4043 61e047a5 Phil Davis
		}
4044
		if (isset($q['mask']) && $q['mask'] <> "") {
4045 0b4e7542 Jean Cyr
			$masktype = $q['mask'];
4046 61e047a5 Phil Davis
		} else {
4047 0b4e7542 Jean Cyr
			$masktype = "";
4048 61e047a5 Phil Davis
		}
4049
		if (isset($q['maskbits']) && $q['maskbits'] <> "") {
4050 0b4e7542 Jean Cyr
			$maskbits = $q['maskbits'];
4051 61e047a5 Phil Davis
		} else {
4052 0b4e7542 Jean Cyr
			$maskbits = "";
4053 61e047a5 Phil Davis
		}
4054
		if (isset($q['maskbitsv6']) && $q['maskbitsv6'] <> "") {
4055 2d46e1e4 Jean Cyr
			$maskbitsv6 = $q['maskbitsv6'];
4056 61e047a5 Phil Davis
		} else {
4057 2d46e1e4 Jean Cyr
			$maskbitsv6 = "";
4058 61e047a5 Phil Davis
		}
4059 2d46e1e4 Jean Cyr
		$this->SetMask(array("type" => $masktype, "bits" => $maskbits, "bitsv6" => $maskbitsv6));
4060 61e047a5 Phil Davis
		if (isset($q['buckets']) && $q['buckets'] <> "") {
4061 420b4538 Renato Botelho
			$this->SetBuckets($q['buckets']);
4062 61e047a5 Phil Davis
		} else {
4063 420b4538 Renato Botelho
			$this->SetBuckets("");
4064 61e047a5 Phil Davis
		}
4065
		if (isset($q['plr']) && $q['plr'] <> "") {
4066 420b4538 Renato Botelho
			$this->SetPlr($q['plr']);
4067 61e047a5 Phil Davis
		} else {
4068 420b4538 Renato Botelho
			$this->SetPlr("");
4069 61e047a5 Phil Davis
		}
4070
		if (isset($q['delay']) && $q['delay'] <> "") {
4071 420b4538 Renato Botelho
			$this->SetDelay($q['delay']);
4072 61e047a5 Phil Davis
		} else {
4073 c2461a56 Ermal
			$this->SetDelay(0);
4074 61e047a5 Phil Davis
		}
4075
		if (isset($q['description']) && $q['description'] <> "") {
4076 d62ba478 Ermal Luçi
			$this->SetDescription($q['description']);
4077 61e047a5 Phil Davis
		} else {
4078 c2461a56 Ermal
			$this->SetDescription("");
4079 61e047a5 Phil Davis
		}
4080 d62ba478 Ermal Luçi
		$this->SetEnabled($q['enabled']);
4081 d4f29a52 Steve Beaver
4082 254581a5 Matt Underscore
		/* Limiter patch */
4083
		if (isset($q['aqm']) && $q['aqm'] <> "") {
4084
				$this->SetAQM($q['aqm']);
4085
		} else {
4086
				$this->SetAQM('droptail');
4087
		}
4088
		// parse AQM arguments
4089
		$aqm_map = getAQMs();
4090
		$selectedParameters = $aqm_map[$this->getAQM()]["parameters"];
4091 5ee16aa6 no
		if (is_array($selectedParameters)) {
4092
			foreach ($selectedParameters as $key => $value) {
4093
				$config_key = 'param_' . $this->GetAQM() . '_' . $key;
4094
				if (isset($q[$config_key]) && $q[$config_key] <> "") {
4095
					$this->SetAQMParameter($key, $q[$config_key]);
4096
				} else {
4097
					$this->SetAQMParameter($key, $value["default"]);
4098
				}
4099 254581a5 Matt Underscore
			}
4100
		}
4101 d4f29a52 Steve Beaver
4102 254581a5 Matt Underscore
		if (isset($q['sched']) && $q['sched'] <> "") {
4103
				$this->SetScheduler($q['sched']);
4104
		} else {
4105 5ee16aa6 no
				$this->SetScheduler('fifo');
4106 254581a5 Matt Underscore
		}
4107
		$scheduler_map = getSchedulers();
4108
		$selectedParameters = $scheduler_map[$this->getScheduler()]["parameters"];
4109 5ee16aa6 no
		if (is_array($selectedParameters)) {
4110
			foreach ($selectedParameters as $key => $value) {
4111
				$config_key = 'param_' . $this->GetScheduler() . '_' . $key;
4112
				if (isset($q[$config_key]) && $q[$config_key] <> "") {
4113
					$this->SetSchedulerParameter($key, $q[$config_key]);
4114
				} else {
4115
					$this->SetSchedulerParameter($key, $value["default"]);
4116
				}
4117 254581a5 Matt Underscore
			}
4118
		}
4119 d4f29a52 Steve Beaver
4120 254581a5 Matt Underscore
		// ecn flag
4121
		$this->SetECN($q['ecn']);
4122 10006140 Harley Peters
		// PIE Flags.
4123
		$this->SetPIE_ONOFF($q['pie_onoff']);
4124
		$this->SetPIE_CAPDROP($q['pie_capdrop']);
4125
		$this->SetPIE_QDELAY($q['pie_qdelay']);
4126
		$this->SetPIE_PDERAND($q['pie_pderand']);
4127 254581a5 Matt Underscore
		/* End limiter patch */
4128 420b4538 Renato Botelho
	}
4129 c25a6b6a Ermal Luçi
4130 d62ba478 Ermal Luçi
	function build_tree() {
4131 1072b933 jim-p
		$tree = " <li><a href=\"firewall_shaper_vinterface.php?pipe=" . htmlspecialchars($this->GetQname()) ."&amp;queue=".htmlspecialchars($this->GetQname()) ."&amp;action=show\">";
4132
		$tree .= htmlspecialchars($this->GetQname()) . "</a>";
4133 d62ba478 Ermal Luçi
		if (is_array($this->subqueues)) {
4134
			$tree .= "<ul>";
4135 4de8f7ba Phil Davis
			foreach ($this->subqueues as $q) {
4136 d62ba478 Ermal Luçi
				$tree .= $q->build_tree();
4137 420b4538 Renato Botelho
			}
4138 d62ba478 Ermal Luçi
			$tree .= "</ul>";
4139 c25a6b6a Ermal Luçi
		}
4140 d62ba478 Ermal Luçi
		$tree .= "</li>";
4141 ce0117f7 Colin Fleming
4142 d62ba478 Ermal Luçi
		return $tree;
4143
	}
4144 c25a6b6a Ermal Luçi
4145 420b4538 Renato Botelho
	function build_rules() {
4146 c9ba2f8a Ermal
		global $config, $time_based_rules;
4147
4148 61e047a5 Phil Davis
		if ($this->GetEnabled() == "") {
4149 8cb1c6e3 Ermal Luçi
			return;
4150 61e047a5 Phil Davis
		}
4151 8cb1c6e3 Ermal Luçi
4152 e7ccf2a5 Ermal
		$pfq_rule = "\npipe ". $this->GetNumber() . " config ";
4153 fa29a6f0 Ermal
		$found = false;
4154 c9ba2f8a Ermal
		$bandwidth = $this->GetBandwidth();
4155
		if (is_array($bandwidth)) {
4156
			foreach ($bandwidth as $bw) {
4157 fbfed5ba Ermal
				if ($bw['bwsched'] != "none") {
4158 2ed21904 Ermal
					if (is_array($config['schedules']) && is_array($config['schedules']['schedule'])) {
4159 d96b96b9 Ermal
						foreach ($config['schedules']['schedule'] as $schedule) {
4160
							if ($bw['bwsched'] == $schedule['name']) {
4161
								if (filter_get_time_based_rule_status($schedule)) {
4162 7c4e07c6 jim-p
									/* pipe throughputs must always be an integer, enforce that restriction again here. */
4163
									$pfq_rule .= " bw ".round(trim($bw['bw']),0).$bw['bwscale'];
4164 61e047a5 Phil Davis
									if (is_numeric($bw['burst']) && ($bw['burst'] > 0)) {
4165 c90d37f3 jim-p
										$pfq_rule .= " burst ".trim($bw['burst']);
4166 61e047a5 Phil Davis
									}
4167 fa29a6f0 Ermal
									$found = true;
4168 d96b96b9 Ermal
									break;
4169
								}
4170 c9ba2f8a Ermal
							}
4171
						}
4172 0b3a76ca Ermal
					} else {
4173 fa29a6f0 Ermal
						$pfq_rule .= " bw 0";
4174 02593e37 Ermal Luçi
						$found = true;
4175 0b3a76ca Ermal
						break;
4176
					}
4177 ec091c89 Ermal
				} else {
4178 7c4e07c6 jim-p
					/* pipe throughputs must always be an integer, enforce that restriction again here. */
4179
					$pfq_rule .= " bw ".round(trim($bw['bw']), 0).$bw['bwscale'];
4180 61e047a5 Phil Davis
					if (is_numeric($bw['burst']) && ($bw['burst'] > 0)) {
4181 c90d37f3 jim-p
						$pfq_rule .= " burst ".trim($bw['burst']);
4182 61e047a5 Phil Davis
					}
4183 02593e37 Ermal Luçi
					$found = true;
4184 ec091c89 Ermal
					break;
4185
				}
4186 c9ba2f8a Ermal
			}
4187 61e047a5 Phil Davis
			if ($found == false) {
4188 fa29a6f0 Ermal
				$pfq_rule .= " bw 0";
4189 61e047a5 Phil Davis
			}
4190
		} else {
4191 ec091c89 Ermal
			$pfq_rule .= " bw 0";
4192 61e047a5 Phil Davis
		}
4193 c9ba2f8a Ermal
4194 61e047a5 Phil Davis
		if ($this->GetQlimit()) {
4195 4981f881 Ermal
			$pfq_rule .= " queue " . $this->GetQlimit();
4196 61e047a5 Phil Davis
		}
4197
		if ($this->GetPlr()) {
4198 d62ba478 Ermal Luçi
			$pfq_rule .= " plr " . $this->GetPlr();
4199 61e047a5 Phil Davis
		}
4200
		if ($this->GetBuckets()) {
4201 d62ba478 Ermal Luçi
			$pfq_rule .= " buckets " . $this->GetBuckets();
4202 61e047a5 Phil Davis
		}
4203
		if ($this->GetDelay()) {
4204 d62ba478 Ermal Luçi
			$pfq_rule .= " delay " . $this->GetDelay();
4205 61e047a5 Phil Davis
		}
4206 2d46e1e4 Jean Cyr
		$this->build_mask_rules($pfq_rule);
4207 d62ba478 Ermal Luçi
4208 254581a5 Matt Underscore
		/* Limiter patch */
4209
		$selectedAQM = getAQMs()[$this->getAQM()];
4210
		if ($selectedAQM) {
4211 50d4c4f2 Matt Underscore
			$pfq_rule .= " " . FormatParameters($selectedAQM["parameter_format"], $this->GetAQMParameters());
4212 254581a5 Matt Underscore
			if ($selectedAQM["ecn"]) {
4213
				if ($this->getECN() == 'on') {
4214
					$pfq_rule .= ' ecn';
4215 75fb1d57 Viktor G
				} elseif (($this->getAQM() != 'red') && ($this->getAQM() != 'gred')) {
4216 254581a5 Matt Underscore
					$pfq_rule .= ' noecn';
4217
				}
4218
			}
4219
		}
4220
		$selectedScheduler = getSchedulers()[$this->getScheduler()];
4221
		if ($selectedScheduler) {
4222 c5c8893b bonald
			$pfq_rule .= "\nsched ". $this->GetNumber() . " config ";
4223
			$pfq_rule .= "pipe ". $this->GetNumber();
4224
			$this->build_mask_rules($pfq_rule);
4225
			$pfq_rule .= " " . FormatParameters($selectedScheduler["parameter_format"], $this->GetSchedulerParameters());			
4226 254581a5 Matt Underscore
			if ($selectedScheduler["ecn"]) {
4227
				if ($this->getECN() == 'on') {
4228
					$pfq_rule .= ' ecn';
4229
				} else {
4230
					$pfq_rule .= ' noecn';
4231
				}
4232
			}
4233 10006140 Harley Peters
			if ($selectedScheduler["pie_onoff"]) {
4234
				if ($this->getPIE_ONOFF() == 'on') {
4235
					$pfq_rule .= 'onoff';
4236
				} else {
4237
					$pfq_rule .= '';
4238
				}
4239
			}
4240
			if ($selectedScheduler["pie_capdrop"]) {
4241
				if ($this->getPIE_CAPDROP() == 'on') {
4242
					$pfq_rule .= ' capdrop';
4243
				} else {
4244
					$pfq_rule .= ' nocapdrop';
4245
				}
4246
			}
4247
			if ($selectedScheduler["pie_qdelay"]) {
4248
				if ($this->getPIE_QDELAY() == 'on') {
4249
					$pfq_rule .= ' ts';
4250
				} else {
4251
					$pfq_rule .= ' dre';
4252
				}
4253
			}
4254
			if ($selectedScheduler["pie_pderand"]) {
4255
				if ($this->getPIE_PDERAND() == 'on') {
4256
					$pfq_rule .= ' derand';
4257
				} else {
4258
					$pfq_rule .= ' noderand';
4259
				}
4260
			}
4261 254581a5 Matt Underscore
		}
4262 f7f33eb3 Ermal
		$pfq_rule .= "\n";
4263 254581a5 Matt Underscore
		/* End patch */
4264 d4f29a52 Steve Beaver
4265 f5130e64 Ermal
		if (!empty($this->subqueues) && count($this->subqueues) > 0) {
4266 61e047a5 Phil Davis
			foreach ($this->subqueues as $q) {
4267
				$pfq_rule .= $q->build_rules();
4268
			}
4269 f5130e64 Ermal
		}
4270 d4f29a52 Steve Beaver
4271 d62ba478 Ermal Luçi
		$pfq_rule .= " \n";
4272 c25a6b6a Ermal Luçi
4273 d62ba478 Ermal Luçi
		return $pfq_rule;
4274 420b4538 Renato Botelho
	}
4275 c25a6b6a Ermal Luçi
4276 420b4538 Renato Botelho
	function update_dn_data(&$data) {
4277 d62ba478 Ermal Luçi
		$this->ReadConfig($data);
4278
	}
4279 c25a6b6a Ermal Luçi
4280 c9ba2f8a Ermal
	function build_javascript() {
4281
		global $g, $config;
4282
4283 8c50a9d8 Jean Cyr
		$javasr = parent::build_javascript();
4284 420b4538 Renato Botelho
4285 c9ba2f8a Ermal
		//build list of schedules
4286
		$schedules = "<option value='none'>none</option>";
4287
		if (is_array($config['schedules']) && is_array($config['schedules']['schedule'])) {
4288
			foreach ($config['schedules']['schedule'] as $schedule) {
4289 61e047a5 Phil Davis
				if ($schedule['name'] <> "") {
4290 c9ba2f8a Ermal
					$schedules .= "<option value='{$schedule['name']}'>{$schedule['name']}</option>";
4291 61e047a5 Phil Davis
				}
4292 c9ba2f8a Ermal
			}
4293
		}
4294
		$bwopt = "";
4295 61e047a5 Phil Davis
		foreach (array("Kb" => "Kbit/s", "Mb" => "Mbit/s", "Gb" => "Gbit/s", "b" => "Bit/s") as $bwidx => $bw) {
4296 c9ba2f8a Ermal
			$bwopt .= "<option value='{$bwidx}'>{$bw}</option>";
4297 61e047a5 Phil Davis
		}
4298 c9ba2f8a Ermal
4299 8c50a9d8 Jean Cyr
		$javasr .= <<<EOD
4300 7da5315d Colin Fleming
<script type='text/javascript'>
4301 0fa05f45 Colin Fleming
//<![CDATA[
4302 c9ba2f8a Ermal
var addBwRowTo = (function() {
4303 3b6dedf3 Stephen Beaver
4304 c9ba2f8a Ermal
	return (function (tableId) {
4305 3b6dedf3 Stephen Beaver
4306 d2466d40 Stephen Beaver
	var table = document.getElementById(tableId);
4307
	var totalrows = table.rows.length -1;
4308 3b6dedf3 Stephen Beaver
4309 d2466d40 Stephen Beaver
	var row = table.insertRow(totalrows + 1);
4310
	var cell1 = row.insertCell(0);
4311
	var cell2 = row.insertCell(1);
4312
	var cell3 = row.insertCell(2);
4313
	var cell4 = row.insertCell(3);
4314
4315
	cell1.innerHTML = "<input type='hidden' value='" + totalrows +"' name='bandwidth_row-" + totalrows + "' /><input type='text' class='form-control' name='bandwidth" + totalrows + "' id='bandwidth" + totalrows + "' />";
4316
	cell2.innerHTML = "<input type='hidden' value='" + totalrows +"' name='bwtype_row-" + totalrows + "' /><select class='form-control' name='bwtype" + totalrows + "'>{$bwopt}</select>";
4317
	cell3.innerHTML = "<input type='hidden' value='" + totalrows +"' name='bwsched_row-" + totalrows + "' /><select class='form-control' name='bwsched" + totalrows + "'>{$schedules}</select>";
4318 27d6a45b jim-p
	cell4.innerHTML = '<a class="btn btn-warning" onclick="removeBwRow(this); return false;" href="#"><i class="fa fa-trash icon-embed-btn"></i>Delete</a>';
4319 d2466d40 Stephen Beaver
4320 c9ba2f8a Ermal
	});
4321
})();
4322
4323
function removeBwRow(el) {
4324 d2466d40 Stephen Beaver
	var d = el.parentNode.parentNode.rowIndex;
4325 3b6dedf3 Stephen Beaver
	document.getElementById('maintable').deleteRow(d);
4326 c9ba2f8a Ermal
}
4327 0f5bd6f8 Stephen Jones
4328
function ceil_func(el){
4329
	el.value = Math.ceil(el.value);
4330
4331
}
4332 0fa05f45 Colin Fleming
//]]>
4333 c9ba2f8a Ermal
</script>
4334
4335
EOD;
4336
4337 420b4538 Renato Botelho
		return $javasr;
4338 c9ba2f8a Ermal
	}
4339
4340 d2466d40 Stephen Beaver
	// Compose a table of bandwidths that can then be inserted into the form using a Form_StaticText
4341 df67ba6a Stephen Beaver
	// The table has been "Bootstrapped" to match the web design while maintaining compatibility with
4342 d2466d40 Stephen Beaver
	// with the javascript in this class
4343
	function build_bwtable() {
4344
		global $config;
4345 3b6dedf3 Stephen Beaver
4346 d2466d40 Stephen Beaver
		$bandwidth = $this->GetBandwidth();
4347
				//build list of schedules
4348
		$schedules = array();
4349
		$schedules[] = "none";//leave none to leave rule enabled all the time
4350
		if (is_array($config['schedules']) && is_array($config['schedules']['schedule'])) {
4351
			foreach ($config['schedules']['schedule'] as $schedule) {
4352 df67ba6a Stephen Beaver
				if ($schedule['name'] != "") {
4353 d2466d40 Stephen Beaver
					$schedules[] = $schedule['name'];
4354
				}
4355
			}
4356
		}
4357 3b6dedf3 Stephen Beaver
4358 df67ba6a Stephen Beaver
		$form = '<div class="table-responsive">';
4359
		$form .= '<table id="maintable" class="table table-hover table-striped">';
4360 d2466d40 Stephen Beaver
		$form .= "<thead><tr>";
4361 df67ba6a Stephen Beaver
		$form .= "<th>Bandwidth</th>";
4362 d2466d40 Stephen Beaver
		//$form .= "<td width='35%'><div id='fifthcolumn'>Burst</div></td>";
4363 df67ba6a Stephen Beaver
		$form .= "<th>Bw type</th>";
4364
		$form .= "<th>Schedule</th>";
4365
		$form .= "<th></th>";
4366 d2466d40 Stephen Beaver
		$form .= "</tr></thead>";
4367
		$form .= "<tbody>";
4368 3b6dedf3 Stephen Beaver
4369 df67ba6a Stephen Beaver
		// If there are no bandwidths defined, make a blank one for convenience
4370 4e322e2c Phil Davis
		if (empty($bandwidth)) {
4371 c4fc5142 Viktor G
			$bandwidth = array(0 => array('bw' => '', 'bwscale' => 'Mb', 'bwsched' => 'none'));
4372 4e322e2c Phil Davis
		}
4373 b37b4034 Phil Davis
4374 d2466d40 Stephen Beaver
		if (is_array($bandwidth)) {
4375
			foreach ($bandwidth as $bwidx => $bw) {
4376 df67ba6a Stephen Beaver
				$form .= '<tr>';
4377
				$form .= '<td class="col-xs-4">';
4378 727ed08b Christian McDonald
				$form .= "<input class='form-control' onchange=\"ceil_func(this)\" type=\"number\" id=\"bandwidth{$bwidx}\" name=\"bandwidth{$bwidx}\" value=\"" . ceil2($bw['bw']) ."\" min=\"0\" step=\"1\"/>";
4379 d2466d40 Stephen Beaver
				//$form .= "</td><td width='20%'>";
4380
				//$form .= "<input class='formfld unknown' size='10' type=\"text\" id=\"burst{$bwidx}\" name=\"burst{$bwidx}\" value=\"{$bw['burst']}\" />";
4381 df67ba6a Stephen Beaver
				$form .= "</td>";
4382
				$form .= '<td class="col-xs-4">';
4383 d2466d40 Stephen Beaver
				$form .= "<select id=\"bwtype{$bwidx}\" name=\"bwtype{$bwidx}\" class=\"form-control\">";
4384 b37b4034 Phil Davis
4385 f95cdbea Chris Buechler
				foreach (array("Kb" => "Kbit/s", "Mb" => "Mbit/s", "b" => "Bit/s") as $bwsidx => $bwscale) {
4386 d2466d40 Stephen Beaver
					$form .= "<option value=\"{$bwsidx}\"";
4387 b37b4034 Phil Davis
4388 d2466d40 Stephen Beaver
					if ($bw['bwscale'] == $bwsidx) {
4389 c4b60a9a Colin Fleming
						$form .= " selected";
4390 d2466d40 Stephen Beaver
					}
4391 b37b4034 Phil Davis
4392 d2466d40 Stephen Beaver
					$form .= ">{$bwscale}</option>";
4393
				}
4394 b37b4034 Phil Davis
4395 d2466d40 Stephen Beaver
				$form .= "</select>";
4396 df67ba6a Stephen Beaver
				$form .= "</td>";
4397
				$form .= '<td class="col-xs-4">';
4398 d2466d40 Stephen Beaver
				$form .= "<select id=\"bwsched{$bwidx}\" name=\"bwsched{$bwidx}\" class=\"form-control\">";
4399 b37b4034 Phil Davis
4400 d2466d40 Stephen Beaver
				foreach ($schedules as $schd) {
4401
					$selected = "";
4402
					if ($bw['bwsched'] == $schd) {
4403 c4b60a9a Colin Fleming
						$selected = "selected";
4404 d2466d40 Stephen Beaver
					}
4405 b37b4034 Phil Davis
4406 d2466d40 Stephen Beaver
					$form .= "<option value='{$schd}' {$selected}>{$schd}</option>";
4407
				}
4408 b37b4034 Phil Davis
4409 d2466d40 Stephen Beaver
				$form .= "</select>";
4410 df67ba6a Stephen Beaver
				$form .= "</td>";
4411
				$form .= '<td>';
4412 27d6a45b jim-p
				$form .= '<a class="btn btn-warning" onclick="removeBwRow(this); return false;"><i class="fa fa-trash icon-embed-btn"></i>' . gettext('Delete') . '</a>';
4413 d2466d40 Stephen Beaver
				$form .= "</td></tr>";
4414
			}
4415
		}
4416 df67ba6a Stephen Beaver
		$form .= "</tbody></table></div><br />";
4417 3b6dedf3 Stephen Beaver
4418 b9bc38c1 NOYB
		$form .= '<a class="btn btn-sm btn-success" onclick="javascript:addBwRowTo(\'maintable\'); return false;" >';
4419 27d6a45b jim-p
		$form .= '<i class="fa fa-plus icon-embed-btn"></i>';
4420
		$form .= gettext("Add Schedule") . "</a>";
4421 3b6dedf3 Stephen Beaver
4422 d2466d40 Stephen Beaver
		return($form);
4423
	}
4424 3b6dedf3 Stephen Beaver
4425 7903dd5e Stephen Beaver
	function build_form() {
4426
		global $g, $config, $pipe, $action, $qname;
4427 c9ba2f8a Ermal
4428
		//build list of schedules
4429
		$schedules = array();
4430
		$schedules[] = "none";//leave none to leave rule enabled all the time
4431
		if (is_array($config['schedules']) && is_array($config['schedules']['schedule'])) {
4432
			foreach ($config['schedules']['schedule'] as $schedule) {
4433 61e047a5 Phil Davis
				if ($schedule['name'] <> "") {
4434 c9ba2f8a Ermal
					$schedules[] = $schedule['name'];
4435 61e047a5 Phil Davis
				}
4436 c9ba2f8a Ermal
			}
4437
		}
4438
4439 7903dd5e Stephen Beaver
4440
		$sform = new Form();
4441 5605a0c4 Stephen Beaver
		$sform->setAction("firewall_shaper.php");
4442 7903dd5e Stephen Beaver
4443
		$section = new Form_Section('Limiters');
4444
4445
		$section->addInput(new Form_Checkbox(
4446
			'enabled',
4447
			'Enable',
4448
			'Enable limiter and its children',
4449
			($this->GetEnabled() == "on"),
4450
			'on'
4451
		));
4452
4453
		$section->addInput(new Form_Input(
4454
			'newname',
4455 40dcb4b6 Phil Davis
			'*Name',
4456 7903dd5e Stephen Beaver
			'text',
4457
			$this->GetQname()
4458
		));
4459 d2466d40 Stephen Beaver
4460 7903dd5e Stephen Beaver
		$section->addInput(new Form_Input(
4461
			'name',
4462
			null,
4463
			'hidden',
4464
			$this->GetQname()
4465
		));
4466 d2466d40 Stephen Beaver
4467 85a236e9 Ermal
		if ($this->GetNumber() > 0) {
4468 7903dd5e Stephen Beaver
			$section->addInput(new Form_Input(
4469
				'number',
4470
				null,
4471
				'hidden',
4472
				$this->GetNumber()
4473
			));
4474
		}
4475 d2466d40 Stephen Beaver
4476
		$bandwidth = $this->GetBandwidth();
4477 7903dd5e Stephen Beaver
4478 c9ba2f8a Ermal
		if (is_array($bandwidth)) {
4479 df67ba6a Stephen Beaver
				$section->addInput(new Form_StaticText(
4480 7903dd5e Stephen Beaver
				'Bandwidth',
4481 d2466d40 Stephen Beaver
				$this->build_bwtable()
4482 3b6dedf3 Stephen Beaver
			));
4483 7903dd5e Stephen Beaver
		}
4484
4485 0b4e7542 Jean Cyr
		$mask = $this->GetMask();
4486 d2466d40 Stephen Beaver
4487 7903dd5e Stephen Beaver
		$section->addInput(new Form_Select(
4488 23f4c08f Stephen Beaver
			'mask',
4489 7903dd5e Stephen Beaver
			'Mask',
4490
			$mask['type'],
4491 b50d30c3 Stephen Beaver
			array('none' => gettext('None'), 'srcaddress' => gettext('Source addresses'), 'dstaddress' => gettext('Destination addresses'))
4492 7903dd5e Stephen Beaver
		))->setHelp('If "source" or "destination" slots is chosen a dynamic pipe with the bandwidth, delay, packet loss ' .
4493
					'and queue size given above will be created for each source/destination IP address encountered, respectively. ' .
4494 f338b271 Felix Wolfsteller
					'This makes it possible to easily specify bandwidth limits per host or subnet.');
4495 d2466d40 Stephen Beaver
4496 7903dd5e Stephen Beaver
		$group = new Form_Group(null);
4497 d2466d40 Stephen Beaver
4498 7903dd5e Stephen Beaver
		$group->add(new Form_Select(
4499
			'maskbits',
4500
			null,
4501
			$mask['bits'],
4502
			array_combine(range(32, 1, -1), range(32, 1, -1))
4503 08dbe1c5 Phil Davis
		))->setHelp('IPv4 mask bits%1$s%2$s', '<br />', '255.255.255.255/?');
4504 d2466d40 Stephen Beaver
4505 7903dd5e Stephen Beaver
		$group->add(new Form_Select(
4506
			'maskbitsv6',
4507
			null,
4508
			$mask['bitsv6'],
4509
			array_combine(range(128, 1, -1), range(128, 1, -1))
4510 08dbe1c5 Phil Davis
		))->setHelp('IPv6 mask bits%1$s%2$s', '<br />', '<span style="font-family:consolas">ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/?</span>');
4511 d2466d40 Stephen Beaver
4512 7903dd5e Stephen Beaver
		$section->add($group);
4513 c25a6b6a Ermal Luçi
4514 7903dd5e Stephen Beaver
		$section->addInput(new Form_Input(
4515
			'description',
4516
			'Description',
4517
			'text',
4518
			$this->GetDescription()
4519 530e4707 NOYB
		))->setHelp('A description may be entered here for administrative reference (not parsed).');
4520 d2466d40 Stephen Beaver
4521 7903dd5e Stephen Beaver
		$sform->add($section);
4522 d2466d40 Stephen Beaver
4523 254581a5 Matt Underscore
		/* Begin limiter patch */
4524
		$aqm_map = getAQMs();
4525
		$scheduler_map = getSchedulers();
4526 d4f29a52 Steve Beaver
4527 254581a5 Matt Underscore
		$section = new Form_Section('Queue');
4528
		$section->addInput(new Form_Select(
4529
				'aqm',
4530
				'Queue Management Algorithm',
4531
				$this->GetAQM(),
4532
				array_map_assoc(function ($k, $v) {
4533
					return [$k, $v["name"]];
4534
				}, $aqm_map)
4535
		))->setHelp('Active queue management (AQM) is the intelligent drop of network packets inside the limiter, ' .
4536
						'when it becomes full or gets close to becoming full, with the goal of reducing ' .
4537
						'network congestion.');
4538 d4f29a52 Steve Beaver
4539 254581a5 Matt Underscore
		$section->addInput(new Form_StaticText(
4540
			'',
4541 50d4c4f2 Matt Underscore
			build_queue_params($aqm_map, $this->GetAQM(), $this->GetAQMParameters(), "aqm")
4542 254581a5 Matt Underscore
		))->setHelp('Specifies the queue management algorithm parameters.');
4543 d4f29a52 Steve Beaver
4544 254581a5 Matt Underscore
		$section->addInput(new Form_Select(
4545
				'sched',
4546
				'Scheduler',
4547
				$this->GetScheduler(),
4548
				array_map_assoc(function ($k, $v) {
4549
					return [$k, $v["name"]];
4550
				}, $scheduler_map)
4551
		))->setHelp('The scheduler manages the sequence of network packets in the limiter\'s queue.');
4552
4553
		$section->addInput(new Form_StaticText(
4554
			'',
4555 50d4c4f2 Matt Underscore
			build_queue_params($scheduler_map, $this->GetScheduler(), $this->GetSchedulerParameters(), "sched")
4556 254581a5 Matt Underscore
		))->setHelp('Specifies the scheduler parameters.');
4557 d4f29a52 Steve Beaver
4558 254581a5 Matt Underscore
		$section->addInput(new Form_Input(
4559
				'qlimit',
4560
				'Queue length',
4561
				'number',
4562
				$this->GetQlimit()
4563
		))->setHelp('Specifies the length of the limiter\'s queue, which the scheduler and AQM are responsible for. ' .
4564
			'This field may be left empty.');
4565 d4f29a52 Steve Beaver
4566 10006140 Harley Peters
		$selectedScheduler = getSchedulers()[$this->getScheduler()];
4567
4568
		if ($selectedScheduler["ecn"]) {
4569
			$section->addInput(new Form_Checkbox(
4570
				'ecn',
4571
				'ECN',
4572
				'Enable Explicit Congestion Notification (ECN)',
4573
				($this->GetECN() == "on"),
4574
				'on'
4575
			))->setHelp('ECN sets a reserved TCP flag when the queue is nearing or exceeding capacity. Not all AQMs or schedulers support this.');
4576
		}
4577
4578
		if ($selectedScheduler["pie_onoff"]) {
4579
			$section->addInput(new Form_Checkbox(
4580
				'pie_onoff',
4581
				'ONOFF',
4582
				'Enable Onoff (onoff,)',
4583
				($this->GetPIE_ONOFF() == "on"),
4584
				'on'
4585
                	))->setHelp('Enable turning PIE on and off depending on queue load.');
4586
		}
4587
4588
		if ($selectedScheduler["pie_capdrop"]) {
4589
			$section->addInput(new Form_Checkbox(
4590
				'pie_capdrop',
4591
				'CAPDROP',
4592
				'Enable Capdrop (capdrop,nocapdrop)',
4593
				($this->GetPIE_CAPDROP() == "on"),
4594
				'on'
4595
			))->setHelp('Enable cap drop adjustment.');
4596
		}
4597
4598
		if ($selectedScheduler["pie_qdelay"]) {
4599
                        $section->addInput(new Form_Checkbox(
4600
                                'pie_qdelay',
4601
                                'QUEUE DELAY TYPE',
4602
                                'Enable Type Of Qdelay (ts,dre)',
4603
                                ($this->GetPIE_QDELAY() == "on"),
4604
                                'on'
4605
                        ))->setHelp('Set queue delay type to timestamps (checked) or departure rate estimation (unchecked).');
4606
                }
4607
4608
		if ($selectedScheduler["pie_pderand"]) {
4609
			$section->addInput(new Form_Checkbox(
4610
				'pie_pderand',
4611
				'PROB DERAND',
4612
				'Enable Drop Probability De-randomisation (derand,noderand)',
4613
				($this->GetPIE_PDERAND() == "on"),
4614
				'on'
4615
			))->setHelp('Enable (checked) or disable (unchecked) drop probability de-randomisation.');
4616
		}
4617 254581a5 Matt Underscore
4618
		$sform->add($section);
4619
		/* End limiter patch */
4620 d4f29a52 Steve Beaver
4621 5f88f964 k-paulius
		$section = new Form_Section('Advanced Options');
4622 d2466d40 Stephen Beaver
4623 7903dd5e Stephen Beaver
		$section->addInput(new Form_Input(
4624
			'delay',
4625 df67ba6a Stephen Beaver
			'Delay (ms)',
4626
			'text',
4627
			$this->GetDelay() > 0 ? $this->GetDelay():null
4628 c3ebf347 NOYB
		))->setHelp('In most cases, zero (0) should specified here (or leave the field empty).');
4629 d2466d40 Stephen Beaver
4630 7903dd5e Stephen Beaver
		$section->addInput(new Form_Input(
4631
			'plr',
4632
			'Packet Loss Rate',
4633
			'number',
4634
			$this->GetPlr(),
4635
			['step' => '0.001', 'min' => '0.000']
4636 530e4707 NOYB
		))->setHelp('In most cases, zero (0) should be specified here (or leave the field empty). ' .
4637 c3ebf347 NOYB
					'A value of 0.001 means one packet in 1000 gets dropped.');
4638 d2466d40 Stephen Beaver
4639 7903dd5e Stephen Beaver
		$section->addInput(new Form_Input(
4640
			'buckets',
4641
			'Bucket size (slots)',
4642
			'number',
4643
			$this->GetBuckets()
4644 c3ebf347 NOYB
		))->setHelp('In most cases, this field should be left empty. It increases the hash size set.');
4645 ce0117f7 Colin Fleming
4646 7903dd5e Stephen Beaver
		$sform->add($section);
4647 d2466d40 Stephen Beaver
4648 7903dd5e Stephen Beaver
		return($sform);
4649 c25a6b6a Ermal Luçi
		}
4650
4651 d62ba478 Ermal Luçi
	function wconfig() {
4652
		$cflink =& get_dn_reference_to_me_in_config($this->GetLink());
4653 61e047a5 Phil Davis
		if (!is_array($cflink)) {
4654 420b4538 Renato Botelho
			$cflink = array();
4655 61e047a5 Phil Davis
		}
4656 d62ba478 Ermal Luçi
		$cflink['name'] = $this->GetQname();
4657
		$cflink['number'] = $this->GetNumber();
4658 420b4538 Renato Botelho
		$cflink['qlimit'] = $this->GetQlimit();
4659
		$cflink['plr'] = $this->GetPlr();
4660
		$cflink['description'] = $this->GetDescription();
4661
4662 c9ba2f8a Ermal
		$bandwidth = $this->GetBandwidth();
4663
		if (is_array($bandwidth)) {
4664
			$cflink['bandwidth'] = array();
4665
			$cflink['bandwidth']['item'] = array();
4666 61e047a5 Phil Davis
			foreach ($bandwidth as $bwidx => $bw) {
4667 c9ba2f8a Ermal
				$cflink['bandwidth']['item'][] = $bw;
4668 61e047a5 Phil Davis
			}
4669 c9ba2f8a Ermal
		}
4670
4671 d62ba478 Ermal Luçi
		$cflink['enabled'] = $this->GetEnabled();
4672
		$cflink['buckets'] = $this->GetBuckets();
4673 0b4e7542 Jean Cyr
		$mask = $this->GetMask();
4674
		$cflink['mask'] = $mask['type'];
4675
		$cflink['maskbits'] = $mask['bits'];
4676 420b4538 Renato Botelho
		$cflink['maskbitsv6'] = $mask['bitsv6'];
4677 d62ba478 Ermal Luçi
		$cflink['delay'] = $this->GetDelay();
4678 d4f29a52 Steve Beaver
4679 254581a5 Matt Underscore
		/* Limiter queue patch */
4680
		$cflink['sched'] = $this->GetScheduler();
4681
		$scheduler_map = getSchedulers();
4682
		$selectedParameters = $scheduler_map[$this->getScheduler()]["parameters"];
4683
		foreach ($selectedParameters as $key => $value) {
4684
			$config_key = 'param_' . $this->GetScheduler() . '_' . $key;
4685 50d4c4f2 Matt Underscore
			$cflink[$config_key] = $this->GetSchedulerParameter($key);
4686 254581a5 Matt Underscore
		}
4687
		$cflink['aqm'] = $this->GetAQM();
4688
		$aqm_map = GetAQMs();
4689
		$selectedParameters = $aqm_map[$this->getAQM()]["parameters"];
4690
		foreach ($selectedParameters as $key => $value) {
4691
			$config_key = 'param_' . $this->GetAQM() . '_' . $key;
4692 50d4c4f2 Matt Underscore
			$cflink[$config_key] = $this->GetAQMParameter($key);
4693 254581a5 Matt Underscore
		}
4694
		$cflink['ecn'] = $this->GetECN();
4695 86e654bf Harley Peters
4696
		$selectedScheduler = getSchedulers()[$this->getScheduler()];
4697
		if ($selectedScheduler["pie_onoff"]) {
4698
			$cflink['pie_onoff'] = $this->GetPIE_ONOFF();
4699
		}
4700
		if ($selectedScheduler["pie_capdrop"]) {
4701
			$cflink['pie_capdrop'] = $this->GetPIE_CAPDROP();
4702
		}
4703
		if ($selectedScheduler["pie_qdelay"]) {
4704
			$cflink['pie_qdelay'] = $this->GetPIE_QDELAY();
4705
		}
4706
		if ($selectedScheduler["pie_pderand"]) {
4707
			$cflink['pie_pderand'] = $this->GetPIE_PDERAND();
4708
		}
4709 254581a5 Matt Underscore
		/* End limiter queue patch */
4710 d62ba478 Ermal Luçi
	}
4711 c25a6b6a Ermal Luçi
4712
}
4713
4714
class dnqueue_class extends dummynet_class {
4715 420b4538 Renato Botelho
	var $pipeparent;
4716
	var $weight;
4717 254581a5 Matt Underscore
	/* Limiter queue patch */
4718
    var $ecn; // ecn 'on' or 'off'
4719 10006140 Harley Peters
	var $pie_onoff;
4720
	var $pie_capdrop;
4721
	var $pie_qdelay;
4722
	var $pie_pderand;
4723 254581a5 Matt Underscore
    var $aqm; // key to aqm_map
4724
    var $aqm_params = array(); // AQM params
4725
	function GetAQM() {
4726
			return $this->aqm;
4727
	}
4728
	function SetAQM($aqm) {
4729
			$this->aqm = $aqm;
4730
	}
4731
	function GetAQMParameters() {
4732
			return $this->aqm_params;
4733
	}
4734 50d4c4f2 Matt Underscore
	function GetAQMParameter($parameter) {
4735
			return $this->aqm_params[$parameter];
4736
	}
4737
	function SetAQMParameter($key, $value) {
4738
			return $this->aqm_params[$key] = $value;
4739
	}
4740 254581a5 Matt Underscore
	function SetAQMParameters($params) {
4741
			$this->aqm_params = $params;
4742
	}
4743
	function GetECN() {
4744
			return $this->ecn;
4745
	}
4746
	function SetECN($ecn) {
4747
			$this->ecn = $ecn;
4748
	}
4749 10006140 Harley Peters
	function GetPIE_ONOFF() {
4750
			return $this->pie_onoff;
4751
	}
4752
	function SetPIE_ONOFF($pie_onoff) {
4753
			$this->pie_onoff = $pie_onoff;
4754
	}
4755
	function GetPIE_CAPDROP() {
4756
			return $this->pie_capdrop;
4757
	}
4758
	function SetPIE_CAPDROP($pie_capdrop) {
4759
			$this->pie_capdrop = $pie_capdrop;
4760
	}
4761
	function GetPIE_QDELAY() {
4762
			return $this->pie_qdelay;
4763
	}
4764
	function SetPIE_QDELAY($pie_qdelay) {
4765
			$this->pie_qdelay = $pie_qdelay;
4766
	}
4767
	function GetPIE_PDERAND() {
4768
			return $this->pie_pderand;
4769
	}
4770
	function SetPIE_PDERAND($pie_pderand) {
4771
			$this->pie_pderand = $pie_pderand;
4772
	}
4773 254581a5 Matt Underscore
	/* End limiter queue patch */
4774 420b4538 Renato Botelho
4775
	function GetWeight() {
4776
		return $this->weight;
4777
	}
4778
	function SetWeight($weight) {
4779
		$this->weight = $weight;
4780
	}
4781 d62ba478 Ermal Luçi
	function GetPipe() {
4782
		return $this->pipeparent;
4783
	}
4784
	function SetPipe($pipe) {
4785
		$this->pipeparent = $pipe;
4786
	}
4787 c25a6b6a Ermal Luçi
4788 d62ba478 Ermal Luçi
	/* Just a stub in case we ever try to call this from the frontend. */
4789 61e047a5 Phil Davis
	function &add_queue($interface, &$queue, &$path, &$input_errors) {
4790
		return;
4791
	}
4792 c25a6b6a Ermal Luçi
4793 d62ba478 Ermal Luçi
	function delete_queue() {
4794
		cleanup_dnqueue_from_rules($this->GetQname());
4795
		unset_dn_object_by_reference($this->GetLink());
4796 795e6194 Viktor G
		mwexec("/sbin/dnctl queue delete " . $this->GetNumber());
4797 420b4538 Renato Botelho
	}
4798 c25a6b6a Ermal Luçi
4799 d62ba478 Ermal Luçi
	function validate_input($data, &$input_errors) {
4800
		parent::validate_input($data, $input_errors);
4801 d4f29a52 Steve Beaver
4802
4803 254581a5 Matt Underscore
		/* Limiter patch */
4804
		$selectedAqm = getAQMs()[$data['aqm']];
4805 cd3cde52 jim-p
		if (!empty($data['aqm']) && !$selectedAqm) {
4806 202411c3 no
			$input_errors[] = gettext("Selected AQM not recognized.");
4807
		}
4808 254581a5 Matt Underscore
		/* End limiter patch */
4809 c25a6b6a Ermal Luçi
4810 d62ba478 Ermal Luçi
		if ($data['weight'] && ((!is_numeric($data['weight'])) ||
4811 4de8f7ba Phil Davis
		    ($data['weight'] < 1 && $data['weight'] > 100))) {
4812 420b4538 Renato Botelho
			$input_errors[] = gettext("Weight must be an integer between 1 and 100.");
4813 61e047a5 Phil Davis
		}
4814 d62ba478 Ermal Luçi
	}
4815 c25a6b6a Ermal Luçi
4816 420b4538 Renato Botelho
	/*
4817
	 * Should search even its children
4818
	 */
4819
	function &find_queue($pipe, $qname) {
4820 61e047a5 Phil Davis
		if ($qname == $this->GetQname()) {
4821 420b4538 Renato Botelho
			return $this;
4822 61e047a5 Phil Davis
		} else {
4823 d62ba478 Ermal Luçi
			return NULL;
4824 61e047a5 Phil Davis
		}
4825 420b4538 Renato Botelho
	}
4826 c25a6b6a Ermal Luçi
4827 d62ba478 Ermal Luçi
	function &find_parentqueue($pipe, $qname) {
4828
		return $this->qparent;
4829 420b4538 Renato Botelho
	}
4830 c25a6b6a Ermal Luçi
4831 420b4538 Renato Botelho
	function &get_queue_list(&$qlist) {
4832 61e047a5 Phil Davis
		if ($this->GetEnabled() == "") {
4833 146f0fad Ermal
			return;
4834 61e047a5 Phil Davis
		}
4835 420b4538 Renato Botelho
		$qlist[$this->GetQname()] = "?" .$this->GetNumber();
4836
	}
4837 c25a6b6a Ermal Luçi
4838 d62ba478 Ermal Luçi
	function ReadConfig(&$q) {
4839 1cbe86f0 Ermal
		if (!empty($q['name']) && !empty($q['newname']) && $q['name'] != $q['newname']) {
4840
			$this->SetQname($q['newname']);
4841
		} else if (!empty($q['newname'])) {
4842
			$this->SetQname($q['newname']);
4843
		} else {
4844
			$this->SetQname($q['name']);
4845
		}
4846 d62ba478 Ermal Luçi
		$this->SetNumber($q['number']);
4847 61e047a5 Phil Davis
		if (isset($q['qlimit']) && $q['qlimit'] <> "") {
4848 420b4538 Renato Botelho
			$this->SetQlimit($q['qlimit']);
4849 61e047a5 Phil Davis
		} else {
4850 420b4538 Renato Botelho
			$this->SetQlimit("");
4851 61e047a5 Phil Davis
		}
4852
		if (isset($q['mask']) && $q['mask'] <> "") {
4853 0b4e7542 Jean Cyr
			$masktype = $q['mask'];
4854 61e047a5 Phil Davis
		} else {
4855 0b4e7542 Jean Cyr
			$masktype = "";
4856 61e047a5 Phil Davis
		}
4857
		if (isset($q['maskbits']) && $q['maskbits'] <> "") {
4858 0b4e7542 Jean Cyr
			$maskbits = $q['maskbits'];
4859 61e047a5 Phil Davis
		} else {
4860 0b4e7542 Jean Cyr
			$maskbits = "";
4861 61e047a5 Phil Davis
		}
4862
		if (isset($q['maskbitsv6']) && $q['maskbitsv6'] <> "") {
4863 2d46e1e4 Jean Cyr
			$maskbitsv6 = $q['maskbitsv6'];
4864 61e047a5 Phil Davis
		} else {
4865 2d46e1e4 Jean Cyr
			$maskbitsv6 = "";
4866 61e047a5 Phil Davis
		}
4867 2d46e1e4 Jean Cyr
		$this->SetMask(array("type" => $masktype, "bits" => $maskbits, "bitsv6" => $maskbitsv6));
4868 61e047a5 Phil Davis
		if (isset($q['buckets']) && $q['buckets'] <> "") {
4869 dda9c67f Renato Botelho
			$this->SetBuckets($q['buckets']);
4870 61e047a5 Phil Davis
		} else {
4871 dda9c67f Renato Botelho
			$this->SetBuckets("");
4872 61e047a5 Phil Davis
		}
4873
		if (isset($q['plr']) && $q['plr'] <> "") {
4874 dda9c67f Renato Botelho
			$this->SetPlr($q['plr']);
4875 61e047a5 Phil Davis
		} else {
4876 dda9c67f Renato Botelho
			$this->SetPlr("");
4877 61e047a5 Phil Davis
		}
4878
		if (isset($q['weight']) && $q['weight'] <> "") {
4879 420b4538 Renato Botelho
			$this->SetWeight($q['weight']);
4880 61e047a5 Phil Davis
		} else {
4881 420b4538 Renato Botelho
			$this->SetWeight("");
4882 61e047a5 Phil Davis
		}
4883
		if (isset($q['description']) && $q['description'] <> "") {
4884 d62ba478 Ermal Luçi
			$this->SetDescription($q['description']);
4885 61e047a5 Phil Davis
		} else {
4886 daacb818 Ermal
			$this->SetDescription("");
4887 61e047a5 Phil Davis
		}
4888 d62ba478 Ermal Luçi
		$this->SetEnabled($q['enabled']);
4889 d4f29a52 Steve Beaver
4890 254581a5 Matt Underscore
		/* Limiter patch */
4891
		if (isset($q['aqm']) && $q['aqm'] <> "") {
4892
				$this->SetAQM($q['aqm']);
4893
		} else {
4894
				$this->SetAQM('droptail');
4895
		}
4896
		// parse AQM arguments
4897
		$aqm_map = getAQMs();
4898
		$selectedParameters = $aqm_map[$this->getAQM()]["parameters"];
4899
		foreach ($selectedParameters as $key => $value) {
4900
			$config_key = 'param_' . $this->GetAQM() . '_' . $key;
4901
			if (isset($q[$config_key]) && $q[$config_key] <> "") {
4902 50d4c4f2 Matt Underscore
				$this->SetAQMParameter($key, $q[$config_key]);
4903 254581a5 Matt Underscore
			} else {
4904 50d4c4f2 Matt Underscore
				$this->SetAQMParameter($key, $value["default"]);
4905 254581a5 Matt Underscore
			}
4906
		}
4907 d4f29a52 Steve Beaver
4908 254581a5 Matt Underscore
		// ecn flag
4909
		$this->SetECN($q['ecn']);
4910 10006140 Harley Peters
		// PIE Flags.
4911
		$this->SetPIE_ONOFF($q['pie_onoff']);
4912
		$this->SetPIE_CAPDROP($q['pie_capdrop']);
4913
		$this->SetPIE_QDELAY($q['pie_qdelay']);
4914
		$this->SetPIE_PDERAND($q['pie_pderand']);
4915 254581a5 Matt Underscore
		/* End limiter patch */
4916 420b4538 Renato Botelho
	}
4917 c25a6b6a Ermal Luçi
4918 d62ba478 Ermal Luçi
	function build_tree() {
4919
		$parent =& $this->GetParent();
4920 1072b933 jim-p
		$tree = " <li><a href=\"firewall_shaper_vinterface.php?pipe=" . htmlspecialchars($parent->GetQname()) ."&amp;queue=" . htmlspecialchars($this->GetQname()) ."&amp;action=show\">";
4921
		$tree .= htmlspecialchars($this->GetQname()) . "</a>";
4922 d62ba478 Ermal Luçi
		$tree .= "</li>";
4923 ce0117f7 Colin Fleming
4924 d62ba478 Ermal Luçi
		return $tree;
4925
	}
4926 c25a6b6a Ermal Luçi
4927 420b4538 Renato Botelho
	function build_rules() {
4928 61e047a5 Phil Davis
		if ($this->GetEnabled() == "") {
4929 420b4538 Renato Botelho
			return;
4930 61e047a5 Phil Davis
		}
4931 8cb1c6e3 Ermal Luçi
4932 d62ba478 Ermal Luçi
		$parent =& $this->GetParent();
4933 420b4538 Renato Botelho
		$pfq_rule = "queue ". $this->GetNumber() . " config pipe " . $parent->GetNumber();
4934 61e047a5 Phil Davis
		if ($this->GetQlimit()) {
4935 420b4538 Renato Botelho
			$pfq_rule .= " queue " . $this->GetQlimit();
4936 61e047a5 Phil Davis
		}
4937
		if ($this->GetWeight()) {
4938 d62ba478 Ermal Luçi
			$pfq_rule .= " weight " . $this->GetWeight();
4939 61e047a5 Phil Davis
		}
4940
		if ($this->GetBuckets()) {
4941 d62ba478 Ermal Luçi
			$pfq_rule .= " buckets " . $this->GetBuckets();
4942 61e047a5 Phil Davis
		}
4943 2d46e1e4 Jean Cyr
		$this->build_mask_rules($pfq_rule);
4944 d4f29a52 Steve Beaver
4945 254581a5 Matt Underscore
		/* Limiter patch */
4946
		$selectedAQM = getAQMs()[$this->getAQM()];
4947
		if ($selectedAQM) {
4948 50d4c4f2 Matt Underscore
			$pfq_rule .= " " . FormatParameters($selectedAQM["parameter_format"], $this->GetAQMParameters());
4949 254581a5 Matt Underscore
			if ($selectedAQM["ecn"]) {
4950
				if ($this->getECN() == 'on') {
4951
					$pfq_rule .= ' ecn';
4952 75fb1d57 Viktor G
				} elseif (($this->getAQM() != 'red') && ($this->getAQM() != 'gred')) {
4953 254581a5 Matt Underscore
					$pfq_rule .= ' noecn';
4954
				}
4955
			}
4956 10006140 Harley Peters
			if ($selectedAQM["pie_onoff"]) {
4957
				if ($this->getPIE_ONOFF() == 'on') {
4958
				$pfq_rule .= 'onoff';
4959
				} else {
4960
					$pfq_rule .= '';
4961
				}
4962
			}
4963
			if ($selectedAQM["pie_capdrop"]) {
4964
				if ($this->getPIE_CAPDROP() == 'on') {
4965
					$pfq_rule .= ' capdrop';
4966
				} else {
4967
					$pfq_rule .= ' nocapdrop';
4968
				}
4969
			}
4970
			if ($selectedAQM["pie_qdelay"]) {
4971
				if ($this->getPIE_QDELAY() == 'on') {
4972
					$pfq_rule .= ' ts';
4973
				} else {
4974
					$pfq_rule .= ' dre';
4975
				}
4976
			}
4977
			if ($selectedAQM["pie_pderand"]) {
4978
				if ($this->getPIE_PDERAND() == 'on') {
4979
					$pfq_rule .= ' derand';
4980
				} else {
4981
					$pfq_rule .= ' noderand';
4982
				}
4983
			}
4984 254581a5 Matt Underscore
		}
4985
		/* End patch */
4986 d4f29a52 Steve Beaver
4987 9b10a6ec Ermal
		$pfq_rule .= "\n";
4988 c25a6b6a Ermal Luçi
4989 d62ba478 Ermal Luçi
		return $pfq_rule;
4990
	}
4991
4992 420b4538 Renato Botelho
	function build_javascript() {
4993 8c50a9d8 Jean Cyr
		return parent::build_javascript();
4994
	}
4995
4996 d2466d40 Stephen Beaver
	function build_form() {
4997
		global $g, $config, $pipe, $action, $qname;
4998
4999
		//build list of schedules
5000
		$schedules = array();
5001
		$schedules[] = "none";//leave none to leave rule enabled all the time
5002
		if (is_array($config['schedules']) && is_array($config['schedules']['schedule'])) {
5003
			foreach ($config['schedules']['schedule'] as $schedule) {
5004
				if ($schedule['name'] <> "") {
5005
					$schedules[] = $schedule['name'];
5006
				}
5007
			}
5008
		}
5009
5010
5011
		$sform = new Form();
5012 5605a0c4 Stephen Beaver
		$sform->setAction("firewall_shaper.php");
5013 d2466d40 Stephen Beaver
		$section = new Form_Section('Limiters');
5014
5015
		$section->addInput(new Form_Checkbox(
5016
			'enabled',
5017
			'Enable',
5018
			'Enable this queue',
5019
			($this->GetEnabled() == "on"),
5020
			'on'
5021
		));
5022
5023
		$section->addInput(new Form_Input(
5024
			'newname',
5025 40dcb4b6 Phil Davis
			'*Name',
5026 d2466d40 Stephen Beaver
			'text',
5027
			$this->GetQname()
5028
		));
5029
5030
		$section->addInput(new Form_Input(
5031
			'name',
5032
			null,
5033
			'hidden',
5034
			$this->GetQname()
5035
		));
5036
5037 85a236e9 Ermal
		if ($this->GetNumber() > 0) {
5038 d2466d40 Stephen Beaver
			$section->addInput(new Form_Input(
5039
				'number',
5040
				null,
5041
				'hidden',
5042
				$this->GetNumber()
5043
			));
5044
		}
5045
5046 0b4e7542 Jean Cyr
		$mask = $this->GetMask();
5047 c25a6b6a Ermal Luçi
5048 d2466d40 Stephen Beaver
		$section->addInput(new Form_Select(
5049 49882789 Stephen Beaver
			'mask',
5050 d2466d40 Stephen Beaver
			'Mask',
5051
			$mask['type'],
5052 b50d30c3 Stephen Beaver
			array('none' => gettext('None'), 'srcaddress' => gettext('Source addresses'), 'dstaddress' => gettext('Destination addresses'))
5053 f338b271 Felix Wolfsteller
		))->setHelp('If "source" or "destination" slots is chosen a dynamic queue with the bandwidth, delay, packet loss ' .
5054 d2466d40 Stephen Beaver
					'and queue size given above will be created for each source/destination IP address encountered, respectively. ' .
5055 f338b271 Felix Wolfsteller
 					'This makes it possible to easily specify bandwidth limits per ' .
5056
 					'host or subnet, usually capped by the bandwidth of the parent ' .
5057
 					'limiter.');
5058 d2466d40 Stephen Beaver
5059
		$group = new Form_Group(null);
5060
5061
		$group->add(new Form_Select(
5062
			'maskbits',
5063
			null,
5064
			$mask['bits'],
5065
			array_combine(range(32, 1, -1), range(32, 1, -1))
5066 08dbe1c5 Phil Davis
		))->setHelp('IPv4 mask bits%1$s%2$s', '<br />', '255.255.255.255/?');
5067 d2466d40 Stephen Beaver
5068
		$group->add(new Form_Select(
5069
			'maskbitsv6',
5070
			null,
5071
			$mask['bitsv6'],
5072
			array_combine(range(128, 1, -1), range(128, 1, -1))
5073 08dbe1c5 Phil Davis
		))->setHelp('IPv6 mask bits%1$s%2$s', '<br />', '<span style="font-family:consolas">ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/?</span>');
5074 d2466d40 Stephen Beaver
5075
		$section->add($group);
5076
5077
		$section->addInput(new Form_Input(
5078
			'description',
5079
			'Description',
5080
			'text',
5081
			$this->GetDescription()
5082 530e4707 NOYB
		))->setHelp('A description may be entered here for administrative reference (not parsed).');
5083 d2466d40 Stephen Beaver
5084
		$sform->add($section);
5085 d4f29a52 Steve Beaver
5086 254581a5 Matt Underscore
		/* Begin limiter patch */
5087
		$aqm_map = getAQMs();
5088 d4f29a52 Steve Beaver
5089 254581a5 Matt Underscore
		$section = new Form_Section('Queue');
5090
		$section->addInput(new Form_Select(
5091
				'aqm',
5092
				'Queue Management Algorithm',
5093
				$this->GetAQM(),
5094
				array_map_assoc(function ($k, $v) {
5095
					return [$k, $v["name"]];
5096
				}, $aqm_map)
5097
		))->setHelp('Active queue management (AQM) is the intelligent drop of network packets inside this limiter\'s queue, ' .
5098
						'when it becomes full or gets close to becoming full, with the goal of reducing ' .
5099
						'network congestion.');
5100 d4f29a52 Steve Beaver
5101 254581a5 Matt Underscore
		$section->addInput(new Form_StaticText(
5102
			'',
5103 50d4c4f2 Matt Underscore
			build_queue_params($aqm_map, $this->GetAQM(), $this->GetAQMParameters(), "aqm")
5104 254581a5 Matt Underscore
		))->setHelp('Specifies the queue management algorithm parameters.');
5105 d4f29a52 Steve Beaver
5106 254581a5 Matt Underscore
		$section->addInput(new Form_Input(
5107
				'qlimit',
5108
				'Queue length',
5109
				'number',
5110
				$this->GetQlimit()
5111
		))->setHelp('Specifies the length of this queue, which the AQM is responsible for.  This field may be left empty.');
5112 d4f29a52 Steve Beaver
5113 10006140 Harley Peters
		$selectedAQM = getAQMs()[$this->getAQM()];
5114 254581a5 Matt Underscore
5115 10006140 Harley Peters
		if ($selectedAQM["ecn"]) {
5116
			$section->addInput(new Form_Checkbox(
5117
				'ecn',
5118
				'ECN',
5119
				'Enable Explicit Congestion Notification (ECN)',
5120
				($this->GetECN() == "on"),
5121
				'on'
5122
			))->setHelp('ECN sets a reserved TCP flag when the queue is nearing or exceeding capacity. Not all AQMs or schedulers support this.');
5123
		}
5124
5125
		if ($selectedAQM["pie_onoff"]) {
5126
			$section->addInput(new Form_Checkbox(
5127
				'pie_onoff',
5128
				'ONOFF',
5129
				'Enable Onoff (onoff,)',
5130
				($this->GetPIE_ONOFF() == "on"),
5131
				'on'
5132
			))->setHelp('Enable turning PIE on and off depending on queue load.');
5133
		}
5134
                                 
5135
		if ($selectedAQM["pie_capdrop"]) {
5136
			$section->addInput(new Form_Checkbox(
5137
				'pie_capdrop',
5138
				'CAPDROP',
5139
				'Enable Capdrop (capdrop,nocapdrop)',
5140
				($this->GetPIE_CAPDROP() == "on"),
5141
				'on'
5142
			))->setHelp('Enable cap drop adjustment.');
5143
		}
5144
                 
5145
		if ($selectedAQM["pie_qdelay"]) {
5146
			$section->addInput(new Form_Checkbox(
5147
				'pie_qdelay',
5148
				'QUEUE DELAY TYPE',
5149
				'Enable Type Of Qdelay (ts,dre)',
5150
				($this->GetPIE_QDELAY() == "on"),
5151
				'on'
5152
			))->setHelp('Set queue delay type to timestamps (checked) or departure rate estimation (unchecked).');
5153
		}
5154
5155
		if ($selectedAQM["pie_pderand"]) {
5156
			$section->addInput(new Form_Checkbox(
5157
				'pie_pderand',
5158
				'PROB DERAND',
5159
				'Enable Drop Probability De-randomisation (derand,noderand)',
5160
				($this->GetPIE_PDERAND() == "on"),
5161
				'on'
5162
			))->setHelp('Enable (checked) or disable (unchecked) drop probability de-randomisation.');
5163
		}
5164 254581a5 Matt Underscore
		$sform->add($section);
5165
		/* End limiter patch */
5166 d2466d40 Stephen Beaver
5167 5f88f964 k-paulius
		$section = new Form_Section('Advanced Options');
5168 d2466d40 Stephen Beaver
5169
		$section->addInput(new Form_Input(
5170
			'weight',
5171
			'Weight',
5172
			'number',
5173
			$this->GetWeight(),
5174
			['min' => '1', 'max' => '100']
5175 3b6dedf3 Stephen Beaver
		))->setHelp('For queues under the same parent this specifies the share that a queue gets(values range from 1 to 100),' .
5176 530e4707 NOYB
					' it can be left blank otherwise.');
5177 ce0117f7 Colin Fleming
5178 d2466d40 Stephen Beaver
		$section->addInput(new Form_Input(
5179
			'plr',
5180
			'Packet Loss Rate',
5181
			'number',
5182
			$this->GetPlr(),
5183
			['step' => '0.001', 'min' => '0.000']
5184 530e4707 NOYB
		))->setHelp('In most cases, zero (0) should be specified here (or leave the field empty). ' .
5185 d2466d40 Stephen Beaver
					'A value of 0.001 means one packet in 1000 gets dropped');
5186 d4f29a52 Steve Beaver
5187 d2466d40 Stephen Beaver
		$section->addInput(new Form_Input(
5188
			'buckets',
5189
			'Bucket size (slots)',
5190
			'number',
5191
			$this->GetBuckets()
5192 530e4707 NOYB
		))->setHelp('In most cases, this field should be left empty. It increases the hash size set');
5193 d2466d40 Stephen Beaver
5194 3b6dedf3 Stephen Beaver
		$section->addInput(new Form_Input(
5195
			'pipe',
5196
			null,
5197
			'hidden',
5198
			$this->GetPipe()
5199
		));
5200
5201 d2466d40 Stephen Beaver
		$sform->add($section);
5202
5203
		return($sform);
5204 d62ba478 Ermal Luçi
	}
5205 c25a6b6a Ermal Luçi
5206 420b4538 Renato Botelho
	function update_dn_data(&$data) {
5207 d62ba478 Ermal Luçi
		$this->ReadConfig($data);
5208
	}
5209 c25a6b6a Ermal Luçi
5210 d62ba478 Ermal Luçi
	function wconfig() {
5211
		$cflink =& get_dn_reference_to_me_in_config($this->GetLink());
5212 61e047a5 Phil Davis
		if (!is_array($cflink)) {
5213 420b4538 Renato Botelho
			$cflink = array();
5214 61e047a5 Phil Davis
		}
5215 d62ba478 Ermal Luçi
		$cflink['name'] = $this->GetQname();
5216
		$cflink['number'] = $this->GetNumber();
5217 420b4538 Renato Botelho
		$cflink['qlimit'] = $this->GetQlimit();
5218
		$cflink['description'] = $this->GetDescription();
5219 d62ba478 Ermal Luçi
		$cflink['weight'] = $this->GetWeight();
5220
		$cflink['enabled'] = $this->GetEnabled();
5221
		$cflink['buckets'] = $this->GetBuckets();
5222 0b4e7542 Jean Cyr
		$mask = $this->GetMask();
5223
		$cflink['mask'] = $mask['type'];
5224
		$cflink['maskbits'] = $mask['bits'];
5225 420b4538 Renato Botelho
		$cflink['maskbitsv6'] = $mask['bitsv6'];
5226 d4f29a52 Steve Beaver
5227 254581a5 Matt Underscore
		/* Limiter queue patch */
5228
		$cflink['aqm'] = $this->GetAQM();
5229
		$aqm_map = GetAQMs();
5230
		$selectedParameters = $aqm_map[$this->getAQM()]["parameters"];
5231
		foreach ($selectedParameters as $key => $value) {
5232
			$config_key = 'param_' . $this->GetAQM() . '_' . $key;
5233 50d4c4f2 Matt Underscore
			$cflink[$config_key] = $this->GetAQMParameter($key);
5234 254581a5 Matt Underscore
		}
5235
		$cflink['ecn'] = $this->GetECN();
5236 86e654bf Harley Peters
5237
		$selectedAQM = getAQMs()[$this->getAQM()];
5238
		if ($selectedAQM["pie_onoff"]) {
5239
			$cflink['pie_onoff'] = $this->GetPIE_ONOFF();
5240
		}
5241
		if ($selectedAQM["pie_capdrop"]) {
5242
			$cflink['pie_capdrop'] = $this->GetPIE_CAPDROP();
5243
		}
5244
		if ($selectedAQM["pie_qdelay"]) {
5245
			$cflink['pie_qdelay'] = $this->GetPIE_QDELAY();
5246
		}
5247
		if ($selectedAQM["pie_pderand"]) {
5248
			$cflink['pie_pderand'] = $this->GetPIE_PDERAND();
5249
		}
5250 254581a5 Matt Underscore
		/* End limiter queue patch */
5251 d62ba478 Ermal Luçi
	}
5252 c25a6b6a Ermal Luçi
}
5253
5254 daee46a5 Helder Pereira
function get_dummynet_name_list() {
5255 ce0117f7 Colin Fleming
5256 daee46a5 Helder Pereira
	$dn_name_list =& get_unique_dnqueue_list();
5257
	$dn_name = array();
5258 61e047a5 Phil Davis
	if (is_array($dn_name_list)) {
5259
		foreach ($dn_name_list as $key => $value) {
5260 daee46a5 Helder Pereira
			$dn_name[] = $key;
5261 61e047a5 Phil Davis
		}
5262
	}
5263 ce0117f7 Colin Fleming
5264 daee46a5 Helder Pereira
	return $dn_name;
5265 ce0117f7 Colin Fleming
5266 daee46a5 Helder Pereira
}
5267
5268
function get_altq_name_list() {
5269
	$altq_name_list =& get_unique_queue_list();
5270
	$altq_name = array();
5271 61e047a5 Phil Davis
	if (is_array($altq_name_list)) {
5272
		foreach ($altq_name_list as $key => $aqobj) {
5273 daee46a5 Helder Pereira
			$altq_name[] = $key;
5274 61e047a5 Phil Davis
		}
5275
	}
5276 ce0117f7 Colin Fleming
5277 daee46a5 Helder Pereira
	return $altq_name;
5278 f63d5b66 Helder Pereira
}
5279 c25a6b6a Ermal Luçi
5280 197bfe96 Ermal Luçi
/*
5281 61e047a5 Phil Davis
 * XXX: TODO Make a class shaper to hide all these functions
5282 197bfe96 Ermal Luçi
 * from the global namespace.
5283
 */
5284
5285 420b4538 Renato Botelho
/*
5286
 * This is a layer violation but for now there is no way
5287 61e047a5 Phil Davis
 * I can find to properly do this with PHP.
5288 197bfe96 Ermal Luçi
 */
5289
function altq_get_default_queue($interface) {
5290
	global $altq_list_queues;
5291 061f78b1 Bill Marquette
5292 197bfe96 Ermal Luçi
	$altq_tmp = $altq_list_queues[$interface];
5293 61e047a5 Phil Davis
	if ($altq_tmp) {
5294 420b4538 Renato Botelho
		return $altq_tmp->GetDefaultQueuePresent();
5295 61e047a5 Phil Davis
	} else {
5296 acebc1ec Ermal
		return false;
5297 61e047a5 Phil Davis
	}
5298 197bfe96 Ermal Luçi
}
5299 061f78b1 Bill Marquette
5300 21a0464c Ermal Luçi
function altq_check_default_queues() {
5301
	global $altq_list_queues;
5302
5303
	$count = 0;
5304
	if (is_array($altq_list_queues)) {
5305 61e047a5 Phil Davis
		foreach ($altq_list_queues as $altq) {
5306
			if ($altq->GetDefaultQueuePresent()) {
5307 21a0464c Ermal Luçi
				$count++;
5308 61e047a5 Phil Davis
			}
5309 21a0464c Ermal Luçi
		}
5310
	}
5311 61e047a5 Phil Davis
	else {
5312
		$count++;
5313
	}
5314 ce0117f7 Colin Fleming
5315 21a0464c Ermal Luçi
	return 0;
5316
}
5317
5318
function &get_unique_queue_list() {
5319
	global $altq_list_queues;
5320 ce0117f7 Colin Fleming
5321 21a0464c Ermal Luçi
	$qlist = array();
5322
	if (is_array($altq_list_queues)) {
5323
		foreach ($altq_list_queues as $altq) {
5324 61e047a5 Phil Davis
			if ($altq->GetEnabled() == "") {
5325 146f0fad Ermal
				continue;
5326 61e047a5 Phil Davis
			}
5327 21a0464c Ermal Luçi
			$tmplist =& $altq->get_queue_list();
5328 146f0fad Ermal
			foreach ($tmplist as $qname => $link) {
5329 61e047a5 Phil Davis
				if ($link->GetEnabled() <> "") {
5330 420b4538 Renato Botelho
					$qlist[$qname] = $link;
5331 61e047a5 Phil Davis
				}
5332 146f0fad Ermal
			}
5333 21a0464c Ermal Luçi
		}
5334
	}
5335
	return $qlist;
5336
}
5337
5338 309ffde9 Ermal Luçi
function &get_unique_dnqueue_list() {
5339 c25a6b6a Ermal Luçi
	global $dummynet_pipe_list;
5340 ce0117f7 Colin Fleming
5341 c25a6b6a Ermal Luçi
	$qlist = array();
5342
	if (is_array($dummynet_pipe_list)) {
5343
		foreach ($dummynet_pipe_list as $dn) {
5344 61e047a5 Phil Davis
			if ($dn->GetEnabled() == "") {
5345 146f0fad Ermal
				continue;
5346 61e047a5 Phil Davis
			}
5347 c25a6b6a Ermal Luçi
			$tmplist =& $dn->get_queue_list();
5348 146f0fad Ermal
			foreach ($tmplist as $qname => $link) {
5349 420b4538 Renato Botelho
				$qlist[$qname] = $link;
5350 146f0fad Ermal
			}
5351 c25a6b6a Ermal Luçi
		}
5352
	}
5353
	return $qlist;
5354
}
5355
5356 197bfe96 Ermal Luçi
function ref_on_altq_queue_list($parent, $qname) {
5357 61e047a5 Phil Davis
	if (isset($GLOBALS['queue_list'][$qname])) {
5358 197bfe96 Ermal Luçi
		$GLOBALS['queue_list'][$qname]++;
5359 61e047a5 Phil Davis
	} else {
5360 197bfe96 Ermal Luçi
		$GLOBALS['queue_list'][$qname] = 1;
5361 61e047a5 Phil Davis
	}
5362 061f78b1 Bill Marquette
5363 197bfe96 Ermal Luçi
	unref_on_altq_queue_list($parent);
5364
}
5365 061f78b1 Bill Marquette
5366 197bfe96 Ermal Luçi
function unref_on_altq_queue_list($qname) {
5367
	$GLOBALS['queue_list'][$qname]--;
5368 61e047a5 Phil Davis
	if ($GLOBALS['queue_list'][$qname] <= 1) {
5369 420b4538 Renato Botelho
		unset($GLOBALS['queue_list'][$qname]);
5370 61e047a5 Phil Davis
	}
5371 197bfe96 Ermal Luçi
}
5372 061f78b1 Bill Marquette
5373 197bfe96 Ermal Luçi
function read_altq_config() {
5374
	global $altq_list_queues, $config;
5375
	$path = array();
5376 ce0117f7 Colin Fleming
5377 c6c398c6 jim-p
	init_config_arr(array('shaper', 'queue'));
5378 197bfe96 Ermal Luçi
	$a_int = &$config['shaper']['queue'];
5379
5380
	$altq_list_queues = array();
5381 ce0117f7 Colin Fleming
5382 61e047a5 Phil Davis
	if (!is_array($config['shaper']['queue'])) {
5383 197bfe96 Ermal Luçi
		return;
5384 61e047a5 Phil Davis
	}
5385 197bfe96 Ermal Luçi
5386
	foreach ($a_int as $key => $conf) {
5387 520ad1a4 Ermal
		$int = $conf['interface'];
5388 5ffeceb6 Stephen Jones
		$root = new altq_root_queue();
5389 520ad1a4 Ermal
		$root->SetInterface($int);
5390 5ffeceb6 Stephen Jones
		$altq_list_queues[$root->GetInterface()] = $root;
5391 520ad1a4 Ermal
		$root->ReadConfig($conf);
5392 197bfe96 Ermal Luçi
		array_push($path, $key);
5393
		$root->SetLink($path);
5394
		if (is_array($conf['queue'])) {
5395
			foreach ($conf['queue'] as $key1 => $q) {
5396
				array_push($path, $key1);
5397 420b4538 Renato Botelho
				/*
5398
				 * XXX: we completely ignore errors here but anyway we must have
5399 92125c97 Ermal Luçi
				 *	checked them before so no harm should be come from this.
5400
				 */
5401 ea51e9f8 Renato Botelho
				$root->add_queue($root->GetInterface(), $q, $path, $input_errors);
5402 197bfe96 Ermal Luçi
				array_pop($path);
5403 420b4538 Renato Botelho
			}
5404 520ad1a4 Ermal
		}
5405 197bfe96 Ermal Luçi
		array_pop($path);
5406
	}
5407
}
5408 0a33f73e Scott Ullrich
5409 c25a6b6a Ermal Luçi
function read_dummynet_config() {
5410
	global $dummynet_pipe_list, $config;
5411
	$path = array();
5412 d62ba478 Ermal Luçi
5413 c6c398c6 jim-p
	init_config_arr(array('dnshaper', 'queue'));
5414 c25a6b6a Ermal Luçi
	$a_int = &$config['dnshaper']['queue'];
5415 2f038c0b Scott Ullrich
5416 c25a6b6a Ermal Luçi
	$dummynet_pipe_list = array();
5417 ce0117f7 Colin Fleming
5418 c6c398c6 jim-p
	if (!count($config['dnshaper']['queue'])) {
5419 c25a6b6a Ermal Luçi
		return;
5420 61e047a5 Phil Davis
	}
5421 c25a6b6a Ermal Luçi
5422
	foreach ($a_int as $key => $conf) {
5423 61e047a5 Phil Davis
		if (empty($conf['name'])) {
5424 420b4538 Renato Botelho
			continue; /* XXX: grrrrrr at php */
5425 61e047a5 Phil Davis
		}
5426 8f2cc9bd Stephen Jones
		$root = new dnpipe_class();
5427 d62ba478 Ermal Luçi
		$root->ReadConfig($conf);
5428 8f2cc9bd Stephen Jones
		$dummynet_pipe_list[$root->GetQname()] = $root;
5429 d62ba478 Ermal Luçi
		array_push($path, $key);
5430
		$root->SetLink($path);
5431
		if (is_array($conf['queue'])) {
5432
			foreach ($conf['queue'] as $key1 => $q) {
5433
				array_push($path, $key1);
5434 420b4538 Renato Botelho
				/*
5435
				 * XXX: we completely ignore errors here but anyway we must have
5436 d62ba478 Ermal Luçi
				 *	checked them before so no harm should be come from this.
5437 420b4538 Renato Botelho
				 */
5438 ea51e9f8 Renato Botelho
				$root->add_queue($root->GetQname(), $q, $path, $input_errors);
5439 c25a6b6a Ermal Luçi
				array_pop($path);
5440 420b4538 Renato Botelho
			}
5441 d62ba478 Ermal Luçi
		}
5442
		array_pop($path);
5443 c25a6b6a Ermal Luçi
	}
5444
}
5445 0a33f73e Scott Ullrich
5446 197bfe96 Ermal Luçi
function get_interface_list_to_show() {
5447
	global $altq_list_queues, $config;
5448 057399e4 Ermal Luçi
	global $shaperIFlist;
5449
5450 197bfe96 Ermal Luçi
	$tree = "";
5451 057399e4 Ermal Luçi
	foreach ($shaperIFlist as $shif => $shDescr) {
5452
		if ($altq_list_queues[$shif]) {
5453 197bfe96 Ermal Luçi
			continue;
5454 4de8f7ba Phil Davis
		} else {
5455 61e047a5 Phil Davis
			if (!is_altq_capable(get_real_interface($shif))) {
5456 0b033d22 Ermal Luçi
				continue;
5457 61e047a5 Phil Davis
			}
5458 7da5315d Colin Fleming
			$tree .= " <li><a href=\"firewall_shaper.php?interface=".$shif."&amp;action=add\">".$shDescr."</a></li>";
5459 197bfe96 Ermal Luçi
		}
5460
	}
5461 ce0117f7 Colin Fleming
5462 197bfe96 Ermal Luçi
	return $tree;
5463
}
5464 061f78b1 Bill Marquette
5465 197bfe96 Ermal Luçi
function filter_generate_altq_queues() {
5466
	global $altq_list_queues;
5467 ce0117f7 Colin Fleming
5468 197bfe96 Ermal Luçi
	read_altq_config();
5469 061f78b1 Bill Marquette
5470 197bfe96 Ermal Luçi
	$altq_rules = "";
5471 61e047a5 Phil Davis
	foreach ($altq_list_queues as $altq) {
5472 197bfe96 Ermal Luçi
		$altq_rules .= $altq->build_rules();
5473 61e047a5 Phil Davis
	}
5474 0f0c6a9e Scott Ullrich
5475 197bfe96 Ermal Luçi
	return $altq_rules;
5476
}
5477 0f0c6a9e Scott Ullrich
5478 85a236e9 Ermal
function dnqueue_find_nextnumber() {
5479
	global $dummynet_pipe_list;
5480
5481
	$dnused = array();
5482
	if (is_array($dummynet_pipe_list)) {
5483
		foreach ($dummynet_pipe_list as $dn) {
5484
			$tmplist =& $dn->get_queue_list();
5485
			foreach ($tmplist as $qname => $link) {
5486 61e047a5 Phil Davis
				if ($link[0] == "?") {
5487 85a236e9 Ermal
					$dnused[$qname] = substr($link, 1);
5488 61e047a5 Phil Davis
				}
5489 85a236e9 Ermal
			}
5490
		}
5491
	}
5492
5493
	sort($dnused, SORT_NUMERIC);
5494
	$dnnumber = 0;
5495
	$found = false;
5496
	foreach ($dnused as $dnnum) {
5497
		if (($dnnum - $dnnumber) > 1) {
5498 89cf3dc0 Renato Botelho
			$dnnumber = $dnnum - 1;
5499 85a236e9 Ermal
			$found = true;
5500
			break;
5501 61e047a5 Phil Davis
		} else {
5502 85a236e9 Ermal
			$dnnumber = $dnnum;
5503 61e047a5 Phil Davis
		}
5504 85a236e9 Ermal
	}
5505
5506 61e047a5 Phil Davis
	if ($found == false) {
5507 85a236e9 Ermal
		$dnnumber++;
5508 61e047a5 Phil Davis
	}
5509 85a236e9 Ermal
5510
	unset($dnused, $dnnum, $found);
5511
	return $dnnumber;
5512
}
5513
5514
function dnpipe_find_nextnumber() {
5515
	global $dummynet_pipe_list;
5516
5517
	$dnused = array();
5518 61e047a5 Phil Davis
	foreach ($dummynet_pipe_list as $dn) {
5519 85a236e9 Ermal
		$dnused[] = $dn->GetNumber();
5520 61e047a5 Phil Davis
	}
5521 85a236e9 Ermal
5522
	sort($dnused, SORT_NUMERIC);
5523
	$dnnumber = 0;
5524
	$found = false;
5525
	foreach ($dnused as $dnnum) {
5526
		if (($dnnum - $dnnumber) > 1) {
5527 89cf3dc0 Renato Botelho
			$dnnumber = $dnnum - 1;
5528 85a236e9 Ermal
			$found = true;
5529
			break;
5530 61e047a5 Phil Davis
		} else {
5531 85a236e9 Ermal
			$dnnumber = $dnnum;
5532 61e047a5 Phil Davis
		}
5533 85a236e9 Ermal
	}
5534
5535 61e047a5 Phil Davis
	if ($found == false) {
5536 85a236e9 Ermal
		$dnnumber++;
5537 61e047a5 Phil Davis
	}
5538 85a236e9 Ermal
5539
	unset($dnused, $dnnum, $found);
5540
	return $dnnumber;
5541
}
5542
5543 d62ba478 Ermal Luçi
function filter_generate_dummynet_rules() {
5544 1ce16cf3 Viktor G
	global $config, $g, $dummynet_pipe_list;
5545 ce0117f7 Colin Fleming
5546 c25a6b6a Ermal Luçi
	read_dummynet_config();
5547 ce0117f7 Colin Fleming
5548 c25a6b6a Ermal Luçi
	$dn_rules = "";
5549 ef7c3a63 Chris Buechler
	$max_qlimit = "100"; // OS default
5550 61e047a5 Phil Davis
	foreach ($dummynet_pipe_list as $dn) {
5551 c25a6b6a Ermal Luçi
		$dn_rules .= $dn->build_rules();
5552 ef7c3a63 Chris Buechler
		$this_qlimit = $dn->GetQlimit();
5553
		if ($this_qlimit > $max_qlimit) {
5554
			$max_qlimit = $this_qlimit;
5555
		}
5556
	}
5557
	if (!is_numericint($max_qlimit)) {
5558
		$max_qlimit = "100";
5559 61e047a5 Phil Davis
	}
5560 e3e5160c Ermal
	if (!empty($dn_rules)) {
5561 7c2468c5 Viktor G
		dummynet_load_module($max_qlimit);
5562 d41e63b6 Ermal
		file_put_contents("{$g['tmp_path']}/rules.limiter", $dn_rules);
5563 795e6194 Viktor G
		mwexec("/sbin/dnctl {$g['tmp_path']}/rules.limiter");
5564 d41e63b6 Ermal
	}
5565 c25a6b6a Ermal Luçi
}
5566 0a33f73e Scott Ullrich
5567 197bfe96 Ermal Luçi
function build_iface_without_this_queue($iface, $qname) {
5568
	global $g, $altq_list_queues;
5569 d34ade52 Michele Di Maria
	global $shaperIFlist;
5570 0a33f73e Scott Ullrich
5571 197bfe96 Ermal Luçi
	$altq =& $altq_list_queues[$iface];
5572 d17c4ee9 Stephen Beaver
5573 61e047a5 Phil Davis
	if ($altq) {
5574 b28e1512 Stephen Beaver
		$scheduler = $altq->GetScheduler();
5575
	}
5576 d17c4ee9 Stephen Beaver
5577 b28e1512 Stephen Beaver
	$form = '<dl class="dl-horizontal">';
5578 d17c4ee9 Stephen Beaver
5579 b28e1512 Stephen Beaver
	$form .= '	<dt>';
5580
	$form .= '		<a href="firewall_shaper.php?interface=' . $iface . '&amp;queue=' . $iface . '&amp;action=show">' . $shaperIFlist[$iface] . '</a>';
5581
	$form .= '	</dt>';
5582
	$form .= '	<dd>';
5583 d17c4ee9 Stephen Beaver
	$form .=		$scheduler;
5584 b28e1512 Stephen Beaver
	$form .= '	</dd>';
5585 d17c4ee9 Stephen Beaver
5586
	$form .= '	<dt>';
5587 b28e1512 Stephen Beaver
	$form .= 'Clone';
5588
	$form .= '	</dt>';
5589
	$form .= '	<dd>';
5590
	$form .= '<a class="btn btn-info btn-xs" href="firewall_shaper_queues.php?interface=';
5591
	$form .= $iface . '&amp;queue=';
5592
	$form .= $qname . '&amp;action=add">';
5593 27d6a45b jim-p
	$form .= '<i class="fa fa-clone icon-embed-btn"></i>';
5594
	$form .= gettext("Clone Shaper to this Interface") . '</a>';
5595 d17c4ee9 Stephen Beaver
	$form .= '	</dd>';
5596 b28e1512 Stephen Beaver
5597
	$form .= '</dl>';
5598 d17c4ee9 Stephen Beaver
5599 dbaf21d4 Renato Botelho
	return $form;
5600 0a33f73e Scott Ullrich
5601 197bfe96 Ermal Luçi
}
5602 0a33f73e Scott Ullrich
5603 2568e151 Christian McDonald
$default_shaper_msg = sprintf(gettext("Welcome to the %s Traffic Shaper."), g_get('product_label')) . "<br />";
5604 806942d0 Stephen Beaver
$dn_default_shaper_msg = $default_shaper_msg;
5605 d62ba478 Ermal Luçi
5606 aadc1358 Phil Davis
$shaper_msg = gettext("The tree on the left navigates through the %s.");
5607
$default_shaper_msg .= sprintf($shaper_msg, gettext("queues")) . "<br />";
5608
$dn_default_shaper_msg .= sprintf($shaper_msg, gettext("limiters")) . "<br />";
5609
5610
$shaper_msg = gettext("Buttons at the bottom represent %s actions and are activated accordingly.");
5611
$default_shaper_msg .= sprintf($shaper_msg, gettext("queue"));
5612
$dn_default_shaper_msg .= sprintf($shaper_msg, gettext("limiter"));
5613
5614 85ea9d46 Steve Beaver
// Check to see if the specified interface has a queue configured
5615
function interface_has_queue($if) {
5616
	global $config;
5617
5618
	if ($config['shaper']) {
5619
		foreach ($config['shaper']['queue'] as $queue) {
5620
			if ($queue['interface'] === $if) {
5621
				return true;
5622
			}
5623
		}
5624
	}
5625
5626
	return false;
5627
}
5628 7140cb27 Stephen Jones
?>