Project

General

Profile

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