Project

General

Profile

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