Project

General

Profile

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