Project

General

Profile

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