Project

General

Profile

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