Project

General

Profile

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