Project

General

Profile

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