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