Project

General

Profile

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