Project

General

Profile

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