Project

General

Profile

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