Project

General

Profile

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