Project

General

Profile

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