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 be40ce0b Chris Buechler
			$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 be40ce0b Chris Buechler
			$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 be40ce0b Chris Buechler
		if ($data['bandwidth'] && (!is_numeric($data['bandwidth'])))
1006 d1bd01ff Ermal
			$input_errors[] = "Bandwidth must be an integer.";
1007 be40ce0b Chris Buechler
		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 be40ce0b Chris Buechler
		$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 931f3890 Richard Connon
		$form .= " /> <a target=\"_new\" href=\"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 be40ce0b Chris Buechler
				$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 be40ce0b Chris Buechler
                        	$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 be40ce0b Chris Buechler
				$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 ff8affb4 Richard Connon
		$cflink['codel'] = trim($this->GetCodel());
2050
		if (empty($cflink['codel']))
2051
			unset($cflink['codel']);
2052 f5881023 Ermal Lu?i
		if ($this->GetLinkshare() <> "") {
2053
			if ($this->GetL_m1() <> "") {
2054
				$cflink['linkshare1'] = $this->GetL_m1();
2055
				$cflink['linkshare2'] = $this->GetL_d();
2056
				$cflink['linkshare'] = "on";
2057
			} else {
2058
				unset($cflink['linkshare']);
2059
				unset($cflink['linkshare1']);
2060
				unset($cflink['linkshare2']);
2061
			}
2062
			if ($this->GetL_m2() <> "") {
2063
				$cflink['linkshare3'] = $this->GetL_m2();
2064
				$cflink['linkshare'] = "on";
2065
			} else {
2066
				unset($cflink['linkshare']);
2067
				unset($cflink['linkshare3']);
2068
			}
2069
		} else {
2070
			unset($cflink['linkshare']);
2071
			unset($cflink['linkshare1']);
2072
			unset($cflink['linkshare2']);
2073
			unset($cflink['linkshare3']);
2074
		}
2075
		if ($this->GetRealtime() <> "") {
2076
			if ($this->GetR_m1() <> "") {
2077
				$cflink['realtime1'] = $this->GetR_m1();
2078
				$cflink['realtime2'] = $this->GetR_d();
2079
				$cflink['realtime'] = "on";
2080
			} else {
2081
				unset($cflink['realtime']);
2082
				unset($cflink['realtime1']);
2083
				unset($cflink['realtime2']);
2084
			}
2085
			if ($this->GetR_m2() <> "") {
2086
				$cflink['realtime3'] = $this->GetR_m2();
2087
				$cflink['realtime'] = "on";
2088
			} else {
2089
				unset($cflink['realtime']);
2090
				unset($cflink['realtime3']);
2091
			}
2092
		} else {
2093
			unset($cflink['realtime']);
2094
			unset($cflink['realtime1']);
2095
			unset($cflink['realtime2']);
2096
			unset($cflink['realtime3']);
2097
		}
2098
		if ($this->GetUpperlimit() <> "") {
2099
			if ($this->GetU_m1() <> "") {
2100
				$cflink['upperlimit1'] = $this->GetU_m1();
2101
				$cflink['upperlimit2'] = $this->GetU_d();
2102
				$cflink['upperlimit'] = "on";
2103
			} else {
2104
				unset($cflink['upperlimit']);
2105
				unset($cflink['upperlimit1']);
2106
				unset($cflink['upperlimit2']);
2107
			}
2108
			if ($this->GetU_m2() <> "") {
2109
				$cflink['upperlimit3'] = $this->GetU_m2();
2110
				$cflink['upperlimit'] = "on";
2111
			} else {
2112
				unset($cflink['upperlimit']);
2113
				unset($cflink['upperlimit3']);
2114
			}
2115
		} else {
2116
			unset($cflink['upperlimit']);
2117
			unset($cflink['upperlimit1']);
2118
			unset($cflink['upperlimit2']);
2119
			unset($cflink['upperlimit3']);
2120 197bfe96 Ermal Luçi
		}
2121
	}
2122 f5881023 Ermal Lu?i
}
2123 061f78b1 Bill Marquette
2124 197bfe96 Ermal Luçi
class cbq_queue extends priq_queue {
2125 f5881023 Ermal Lu?i
	var $qborrow = "";
2126 061f78b1 Bill Marquette
2127 197bfe96 Ermal Luçi
	function GetBorrow() {
2128
		return $this->qborrow;
2129 061f78b1 Bill Marquette
	}
2130 197bfe96 Ermal Luçi
	function SetBorrow($borrow) {
2131
		$this->qborrow = $borrow;
2132
	}
2133 70b139a3 Chris Buechler
	function CanHaveChildren() {
2134 f5881023 Ermal Lu?i
		return true;
2135 92125c97 Ermal Luçi
	}
2136 197bfe96 Ermal Luçi
2137 92125c97 Ermal Luçi
	function &add_queue($interface, &$qname, &$path, &$input_errors) {
2138 197bfe96 Ermal Luçi
2139
		if (!is_array($this->subqueues))
2140 f5881023 Ermal Lu?i
			$this->subqueues = array();
2141 62150088 Ermal Lu?i
		$q =& new cbq_queue();
2142 197bfe96 Ermal Luçi
		$q->SetInterface($this->GetInterface());
2143
		$q->SetParent(&$this);
2144 92125c97 Ermal Luçi
		$q->ReadConfig($qname);
2145 40de74f5 Ermal Luçi
                $q->validate_input($qname, $input_errors);
2146
                if (count($input_errors)) {
2147 00ca3fb1 Ermal
			log_error("SHAPER: could not create queue " . $q->GetQname() . " on interface {$interface} because: " . print_r($input_errors, true));
2148 40de74f5 Ermal Luçi
                        return $q;
2149
                }
2150
                switch ($q->GetBwscale()) {
2151 f5881023 Ermal Lu?i
                case "%":
2152
                	$myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
2153
                        break;
2154
                default:
2155
                	$myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
2156
                        break;
2157 40de74f5 Ermal Luçi
                }
2158
                $q->SetAvailableBandwidth($myBw);
2159
                $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
2160
2161 197bfe96 Ermal Luçi
		$q->SetEnabled("on");
2162 92125c97 Ermal Luçi
		$q->SetLink($path);
2163
		$this->subqueues[$q->GetQName()] = &$q;
2164 197bfe96 Ermal Luçi
		ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
2165
		if (is_array($qname['queue'])) {
2166 f5881023 Ermal Lu?i
			foreach ($qname['queue'] as $key1 => $que) {
2167
				array_push($path, $key1);
2168
				$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
2169
				array_pop($path);
2170
			}
2171 92125c97 Ermal Luçi
		}
2172 197bfe96 Ermal Luçi
2173
		return $q;
2174 f5881023 Ermal Lu?i
	}
2175 a843b04f Ermal Luçi
2176 f5881023 Ermal Lu?i
	function copy_queue($interface, &$cflink) {
2177 a843b04f Ermal Luçi
2178 f5881023 Ermal Lu?i
		$cflink['interface'] = $interface;
2179
		$cflink['qlimit'] = trim($this->GetQlimit());
2180
		if (empty($clink['qlimit']))
2181
			unset($cflink['qlimit']);
2182
		$cflink['priority'] = trim($this->GetQpriority());
2183
		if (empty($cflink['priority']))
2184
			unset($cflink['priority']);
2185
		$cflink['name'] = $this->GetQname();
2186
		$cflink['description'] = trim($this->GetDescription());
2187
		if (empty($cflink['description']))
2188
			unset($cflink['description']);
2189
		$cflink['bandwidth'] = $this->GetBandwidth();
2190
		$cflink['bandwidthtype'] = $this->GetBwscale();
2191
		$cflink['enabled'] = trim($this->GetEnabled());
2192
		if (empty($cflink['enabled']))
2193
			unset($cflink['enabled']);
2194
		$cflink['default'] = trim($this->GetDefault());
2195
		if (empty($cflink['default']))
2196
			unset($cflink['default']);
2197
		$cflink['red'] = trim($this->GetRed());
2198
		if (empty($cflink['red']))
2199
			unset($cflink['red']);
2200
		$cflink['rio'] = trim($this->GetRio());
2201
		if (empty($cflink['rio']))
2202
			unset($cflink['rio']);
2203
		$cflink['ecn'] = trim($this->GetEcn());
2204
		if (empty($cflink['ecn']))
2205
			unset($cflink['ecn']);
2206
		$cflink['borrow'] = trim($this->GetBorrow());
2207
		if (empty($cflink['borrow']))
2208
			unset($cflink['borrow']);
2209
		if (is_array($this->queues)) {
2210
			$cflinkp['queue'] = array();
2211
			foreach ($this->subqueues as $q) {
2212
				$cflink['queue'][$q->GetQname()] = array();
2213
				$q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
2214
			}
2215 a843b04f Ermal Luçi
		}
2216 f5881023 Ermal Lu?i
	}
2217 ce0117f7 Colin Fleming
2218 f5881023 Ermal Lu?i
	/*
2219
	 * Should search even its children
2220
	 */
2221
	function &find_queue($interface, $qname) {
2222
		if ($qname == $this->GetQname())
2223
			return $this;
2224
		foreach ($this->subqueues as $q) {
2225
			$result =& $q->find_queue("", $qname);
2226 197bfe96 Ermal Luçi
			if ($result)
2227 f5881023 Ermal Lu?i
				return $result;
2228 92125c97 Ermal Luçi
		}
2229 f5881023 Ermal Lu?i
	}
2230 197bfe96 Ermal Luçi
2231
	function &find_parentqueue($interface, $qname) {
2232 f5881023 Ermal Lu?i
		if ($this->subqueues[$qname])
2233
			return $this;
2234
		foreach ($this->subqueues as $q) {
2235
			$result = $q->find_parentqueue("", $qname);
2236 197bfe96 Ermal Luçi
			if ($result)
2237
				return $result;
2238
		}
2239 f5881023 Ermal Lu?i
	}
2240 197bfe96 Ermal Luçi
2241 f5881023 Ermal Lu?i
	function delete_queue() {
2242
		unref_on_altq_queue_list($this->GetQname());
2243
		cleanup_queue_from_rules($this->GetQname());
2244
		foreach ($this->subqueues as $q) {
2245
		$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
2246
			$q->delete_queue();
2247 92125c97 Ermal Luçi
		}
2248 f5881023 Ermal Lu?i
		unset_object_by_reference($this->GetLink());
2249
	}
2250 ce0117f7 Colin Fleming
2251 197bfe96 Ermal Luçi
	function validate_input($data, &$input_errors) {
2252
		parent::validate_input($data, $input_errors);
2253 ce0117f7 Colin Fleming
2254 197bfe96 Ermal Luçi
		if ($data['priority'] > 7)
2255 dbaf21d4 Renato Botelho
				$input_errors[] = gettext("Priority must be an integer between 1 and 7.");
2256 2c072899 jim-p
		$reqdfields[] = "bandwidth";
2257 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidth");
2258 2c072899 jim-p
		$reqdfields[] = "bandwidthtype";
2259 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidthtype");
2260 061f78b1 Bill Marquette
2261 40de74f5 Ermal Luçi
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
2262 ce0117f7 Colin Fleming
2263 40de74f5 Ermal Luçi
		if ($data['bandwidth'] && !is_numeric($data['bandwidth']))
2264 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("Bandwidth must be an integer.");
2265 92125c97 Ermal Luçi
2266 40de74f5 Ermal Luçi
2267 f5881023 Ermal Lu?i
		if ($data['bandwidth'] < 0)
2268 dbaf21d4 Renato Botelho
                       $input_errors[] = gettext("Bandwidth cannot be negative.");
2269 40de74f5 Ermal Luçi
2270 f5881023 Ermal Lu?i
		if ($data['bandwidthtype'] == "%") {
2271
			if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
2272 dbaf21d4 Renato Botelho
				$input_errors[] = gettext("Bandwidth in percentage should be between 1 and 100 bounds.");
2273 f5881023 Ermal Lu?i
		}
2274 40de74f5 Ermal Luçi
2275 a2f70da3 Ermal Luçi
/*
2276 f61dc8e6 Ermal
		$parent =& $this->GetParent();
2277
		switch ($data['bandwidthtype']) {
2278
		case "%":
2279
			$myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
2280
			break;
2281
		default:
2282
			$mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
2283
			break;
2284
		}
2285 3a54efed Ermal Luçi
                if ($parent->GetAvailableBandwidth() < floatval($myBw))
2286 70b139a3 Chris Buechler
                        $input_errors[] = "The sum of the children bandwidth exceeds that of the parent.";
2287 a2f70da3 Ermal Luçi
*/
2288 92125c97 Ermal Luçi
	}
2289 f5881023 Ermal Lu?i
2290
	function ReadConfig(&$q) {
2291
		parent::ReadConfig($q);
2292
		if (!empty($q['borrow']))
2293 197bfe96 Ermal Luçi
			$this->SetBorrow("on");
2294 7ed9c6ac Ermal
		else
2295
			$this->SetBorrow("");
2296 f5881023 Ermal Lu?i
	}
2297 ce0117f7 Colin Fleming
2298 197bfe96 Ermal Luçi
	function build_javascript() {
2299
		return parent::build_javascript();
2300
	}
2301 061f78b1 Bill Marquette
2302 197bfe96 Ermal Luçi
	function build_tree() {
2303 7da5315d Colin Fleming
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface()."&amp;queue=" . $this->GetQname()."&amp;action=show"; 
2304 f5881023 Ermal Lu?i
		$tree .= "\" ";
2305
		$tmpvalue = trim($this->GetDefault());
2306
		if (!empty($tmpvalue))
2307
			$tree .= " class=\"navlnk\"";
2308
		$tree .= " >" . $this->GetQname() . "</a>";
2309
		if (is_array($this->subqueues)) {
2310
			$tree .= "<ul>";
2311
			foreach ($this->subqueues as $q)  {
2312
				$tree .= $q->build_tree();
2313
			}	
2314
			$tree .= "</ul>";
2315
		}
2316
		$tree .= "</li>";
2317
		return $tree;
2318 197bfe96 Ermal Luçi
	}
2319 ce0117f7 Colin Fleming
2320 70b139a3 Chris Buechler
	/* Even this should take children into consideration */
2321 9d0b0635 Ermal
	function build_rules(&$default = false) {
2322 f5881023 Ermal Lu?i
		$pfq_rule = "queue ". $this->qname;
2323
		if ($this->GetInterface())
2324
			$pfq_rule .= " on ".get_real_interface($this->GetInterface());
2325
		if ($this->GetBandwidth() && $this->GetBwscale())
2326
			$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
2327
		$tmpvalue = $this->GetQpriority();
2328
		if (!empty($tmpvalue))
2329
			$pfq_rule .= " priority " . $this->GetQpriority();
2330
		$tmpvalue = trim($this->GetQlimit());
2331
		if (!empty($tmpvalue))
2332
			$pfq_rule .= " qlimit " . $this->GetQlimit();
2333 8edaa92c Ermal
		if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetBorrow() || $this->GetCodel()) {
2334 f5881023 Ermal Lu?i
			$pfq_rule .= " cbq ( ";
2335
			$tmpvalue = trim($this->GetRed());
2336
			if (!empty($tmpvalue)) {
2337
				$comma = 1;
2338
				$pfq_rule .= " red ";
2339
			}
2340 8edaa92c Ermal
			$tmpvalue = trim($this->GetCodel());
2341
			if (!empty($tmpvalue)) {
2342
				$comma = 1;
2343
				$pfq_rule .= " codel ";
2344
			}
2345 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetRio());
2346
			if (!empty($tmpvalue)) {
2347
				if ($comma) 
2348
					$pfq_rule .= " ,";
2349
				$comma = 1;
2350
				$pfq_rule .= " rio ";
2351
			}
2352
			$tmpvalue = trim($this->GetEcn());
2353
			if (!empty($tmpvalue)) {
2354
				if ($comma) 
2355
					$pfq_rule .= " ,";
2356
				$comma = 1;
2357
				$pfq_rule .= " ecn ";
2358
			}
2359
			$tmpvalue = trim($this->GetDefault());
2360
			if (!empty($tmpvalue)) {
2361
				if ($comma)
2362
					$pfq_rule .= " ,";
2363
				$comma = 1;
2364
				$pfq_rule .= " default ";
2365 ef8fca71 Ermal
				$default = true;
2366 f5881023 Ermal Lu?i
			}
2367
			$tmpvalue = trim($this->GetBorrow());
2368
			if (!empty($tmpvalue)) {
2369
				if ($comma)
2370
					$pfq_rule .= ", ";
2371
				$pfq_rule .= " borrow ";
2372 92125c97 Ermal Luçi
			}
2373 f5881023 Ermal Lu?i
			$pfq_rule .= " ) ";
2374
		} 
2375
		if (count($this->subqueues)) {
2376
			$i = count($this->subqueues);
2377
			$pfq_rule .= " { ";
2378
			foreach ($this->subqueues as $qkey => $qnone) {
2379
				if ($i > 1) {
2380
					$i--;
2381
					$pfq_rule .= " {$qkey}, ";
2382
				} else
2383
					$pfq_rule .= " {$qkey} ";
2384
			}
2385
			$pfq_rule .= " } \n";
2386
			foreach ($this->subqueues as $q)
2387 9d0b0635 Ermal
				$pfq_rule .= $q->build_rules($default);
2388 f5881023 Ermal Lu?i
		}
2389 92125c97 Ermal Luçi
2390 f5881023 Ermal Lu?i
		$pfq_rule .= " \n";
2391
		return $pfq_rule;
2392 92125c97 Ermal Luçi
	}
2393
2394
	function build_form() {
2395 f5e511d3 Ermal
		$form = parent::build_form();
2396
		$form .= "<tr>";
2397 7da5315d Colin Fleming
		$form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Bandwidth") . "</td>";
2398 92125c97 Ermal Luçi
		$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
2399
		if ($this->GetBandwidth() > 0)
2400 f5881023 Ermal Lu?i
			$form .= htmlspecialchars($this->GetBandwidth());
2401 6f1bcc36 Colin Fleming
		$form .= "\" />";
2402 197bfe96 Ermal Luçi
		$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
2403 92125c97 Ermal Luçi
		$form .= "<option value=\"Gb\"";
2404
		if ($this->GetBwscale() == "Gb")
2405 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2406 18efed8b Carlos Eduardo Ramos
		$form .= ">" . gettext("Gbit/s") . "</option>";
2407 92125c97 Ermal Luçi
		$form .= "<option value=\"Mb\"";
2408
		if ($this->GetBwscale() == "Mb")
2409 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2410 18efed8b Carlos Eduardo Ramos
		$form .= ">" . gettext("Mbit/s") . "</option>";
2411 92125c97 Ermal Luçi
		$form .= "<option value=\"Kb\"";
2412
		if ($this->GetBwscale() == "Kb")
2413 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2414 18efed8b Carlos Eduardo Ramos
		$form .= ">" . gettext("Kbit/s") . "</option>";
2415 10c526e4 Darren Embry
		$form .= "<option value=\"b\"";
2416 92125c97 Ermal Luçi
		if ($this->GetBwscale() == "b")
2417 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2418 18efed8b Carlos Eduardo Ramos
		$form .= ">" . gettext("Bit/s") . "</option>";
2419 92125c97 Ermal Luçi
		$form .= "<option value=\"%\"";
2420
		if ($this->GetBwscale() == "%")
2421 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2422 92125c97 Ermal Luçi
		$form .= ">%</option>";
2423 0fa05f45 Colin Fleming
		$form .= "</select> <br/>";
2424 dbaf21d4 Renato Botelho
		$form .= "<span class=\"vexpl\">" . gettext("Choose the amount of bandwidth for this queue");
2425 92125c97 Ermal Luçi
		$form .= "</span></td></tr>";
2426 dbaf21d4 Renato Botelho
		$form .= "<tr><td class=\"vncellreq\">" . gettext("Scheduler specific options") . "</td>";
2427 197bfe96 Ermal Luçi
		$form .= "<td class=\"vtable\"><input type=\"checkbox\" id=\"borrow\" name=\"borrow\"";
2428 f5881023 Ermal Lu?i
		if($this->GetBorrow() == "on") 
2429 ce0117f7 Colin Fleming
			$form .=  " checked=\"checked\" ";
2430 6f1bcc36 Colin Fleming
		$form .= " /> " . gettext("Borrow from other queues when available") . "<br/></td></tr>";
2431 197bfe96 Ermal Luçi
2432 92125c97 Ermal Luçi
		return $form;
2433
	}
2434 197bfe96 Ermal Luçi
2435
	function update_altq_queue_data(&$data) { 
2436
		$this->ReadConfig($data);
2437
	}
2438 061f78b1 Bill Marquette
2439 92125c97 Ermal Luçi
	function wconfig() {
2440 197bfe96 Ermal Luçi
		$cflink =& get_reference_to_me_in_config($this->GetLink());
2441 f5881023 Ermal Lu?i
		if (!is_array($cflink))
2442
			$cflink = array();
2443
		$cflink['interface'] = $this->GetInterface();
2444
		$cflink['qlimit'] = trim($this->GetQlimit());
2445
		if (empty($cflink['qlimit']))
2446
			unset($cflink['qlimit']);
2447
		$cflink['priority'] = $this->GetQpriority();
2448
		if (empty($cflink['priority']))
2449
			unset($cflink['priority']);
2450
		$cflink['name'] = $this->GetQname();
2451
		$cflink['description'] = $this->GetDescription();
2452
		if (empty($cflink['description']))
2453
			unset($cflink['description']);
2454
		$cflink['bandwidth'] = $this->GetBandwidth();
2455
		$cflink['bandwidthtype'] = $this->GetBwscale();
2456
		$cflink['enabled'] = trim($this->GetEnabled());
2457
		if (empty($cflink['enabled']))
2458
			unset($cflink['enabled']);
2459
		$cflink['default'] = trim($this->GetDefault());
2460
		if (empty($cflink['default']))
2461
			unset($cflink['default']);
2462
		$cflink['red'] = trim($this->GetRed());
2463
		if (empty($cflink['red']))
2464
			unset($cflink['red']);
2465
		$cflink['rio'] = trim($this->GetRio());
2466
		if (empty($cflink['rio']))
2467
			unset($cflink['rio']);
2468
		$cflink['ecn'] = trim($this->GetEcn());
2469
		if (empty($cflink['ecn']))
2470
			unset($cflink['ecn']);
2471 ff8affb4 Richard Connon
		$cflink['codel'] = trim($this->GetCodel());
2472
		if (empty($cflink['codel']))
2473
			unset($cflink['codel']);
2474 f5881023 Ermal Lu?i
		$cflink['borrow'] = trim($this->GetBorrow());
2475
		if (empty($cflink['borrow']))
2476
			unset($cflink['borrow']);
2477
	}
2478 197bfe96 Ermal Luçi
}
2479 061f78b1 Bill Marquette
2480 2b5caa0e Ermal Luçi
class fairq_queue extends priq_queue {
2481 f5881023 Ermal Lu?i
	var $hogs;
2482
	var $buckets;
2483 2b5caa0e Ermal Luçi
2484
	function GetBuckets() {
2485
		return $this->buckets;
2486
	}
2487
	function SetBuckets($buckets) {
2488 ae3d3adb Ermal Luçi
		$this->buckets = $buckets;
2489 2b5caa0e Ermal Luçi
	}
2490
	function GetHogs() {
2491
		return $this->hogs;
2492
	}
2493
	function SetHogs($hogs) {
2494 ae3d3adb Ermal Luçi
		$this->hogs = $hogs;
2495 2b5caa0e Ermal Luçi
	}
2496 70b139a3 Chris Buechler
	function CanHaveChildren() {
2497 2b5caa0e Ermal Luçi
		return false;
2498
	}
2499
2500
2501
	function copy_queue($interface, &$cflink) {
2502
                $cflink['interface'] = $interface;
2503
                $cflink['qlimit'] = $this->GetQlimit();
2504
                $cflink['priority'] = $this->GetQpriority();
2505
                $cflink['name'] = $this->GetQname();
2506
                $cflink['description'] = $this->GetDescription();
2507
                $cflink['bandwidth'] = $this->GetBandwidth();
2508
                $cflink['bandwidthtype'] = $this->GetBwscale();
2509
                $cflink['enabled'] = $this->GetEnabled();
2510
                $cflink['default'] = $this->GetDefault();
2511
                $cflink['red'] = $this->GetRed();
2512
                $cflink['rio'] = $this->GetRio();
2513
                $cflink['ecn'] = $this->GetEcn();
2514 8774ca6e Ermal Luçi
                $cflink['buckets'] = $this->GetBuckets();
2515
		$cflink['hogs'] = $this->GetHogs();
2516 2b5caa0e Ermal Luçi
	}
2517 ce0117f7 Colin Fleming
2518 2b5caa0e Ermal Luçi
	/*
2519 70b139a3 Chris Buechler
	 * Should search even its children
2520 2b5caa0e Ermal Luçi
	 */
2521
	function &find_queue($interface, $qname) {
2522
		if ($qname == $this->GetQname())
2523
			return $this;
2524
	}
2525
2526 62150088 Ermal Lu?i
	function find_parentqueue($interface, $qname) { return; }
2527 2b5caa0e Ermal Luçi
2528
	function delete_queue() {
2529
		unref_on_altq_queue_list($this->GetQname());
2530
		cleanup_queue_from_rules($this->GetQname());
2531
		unset_object_by_reference($this->GetLink());
2532
	}
2533 ce0117f7 Colin Fleming
2534 2b5caa0e Ermal Luçi
	function validate_input($data, &$input_errors) {
2535
		parent::validate_input($data, $input_errors);
2536 ce0117f7 Colin Fleming
2537 2b5caa0e Ermal Luçi
		if ($data['priority'] > 255)
2538 dbaf21d4 Renato Botelho
				$input_errors[] = gettext("Priority must be an integer between 1 and 255.");
2539 2c072899 jim-p
		$reqdfields[] = "bandwidth";
2540 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidth");
2541 2c072899 jim-p
		$reqdfields[] = "bandwidthtype";
2542 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidthtype");
2543 2b5caa0e Ermal Luçi
2544
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
2545 ce0117f7 Colin Fleming
2546 2b5caa0e Ermal Luçi
		if ($data['bandwidth'] && !is_numeric($data['bandwidth']))
2547 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("Bandwidth must be an integer.");
2548 2b5caa0e Ermal Luçi
2549
2550 dbaf21d4 Renato Botelho
		if ($data['bandwidth'] < 0)
2551
			$input_errors[] = gettext("Bandwidth cannot be negative.");
2552 2b5caa0e Ermal Luçi
2553
2554 dbaf21d4 Renato Botelho
		if ($data['bandwidthtype'] == "%") {
2555
			if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
2556
				$input_errors[] = gettext("Bandwidth in percentage should be between 1 and 100 bounds.");
2557
		}
2558 2b5caa0e Ermal Luçi
2559
/*
2560
           	$parent =& $this->GetParent();
2561
           	switch ($data['bandwidthtype']) {
2562
                       case "%":
2563
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
2564
                       default:
2565
                             $mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
2566
                             break;
2567
           	}
2568
                if ($parent->GetAvailableBandwidth() < floatval($myBw))
2569 70b139a3 Chris Buechler
                        $input_errors[] = "The sum of children bandwidth exceeds that of the parent.";
2570 2b5caa0e Ermal Luçi
*/
2571
	}
2572 ce0117f7 Colin Fleming
2573 2b5caa0e Ermal Luçi
	function ReadConfig(&$q) {
2574
		parent::ReadConfig($q);
2575 f5881023 Ermal Lu?i
		if (!empty($q['buckets']))
2576 2b5caa0e Ermal Luçi
			$this->SetBuckets($q['buckets']);
2577 7ed9c6ac Ermal
		else
2578
			$this->SetBuckets("");
2579 f5881023 Ermal Lu?i
		if (!empty($q['hogs']) && is_valid_shaperbw($q['hogs']))
2580 2b5caa0e Ermal Luçi
			$this->SetHogs($q['hogs']);
2581 7ed9c6ac Ermal
		else
2582
			$this->SetHogs("");
2583 2b5caa0e Ermal Luçi
	}
2584 ce0117f7 Colin Fleming
2585 2b5caa0e Ermal Luçi
	function build_javascript() {
2586
		return parent::build_javascript();
2587
	}
2588
2589
	function build_tree() {
2590
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . 
2591 7da5315d Colin Fleming
		$this->GetInterface()."&amp;queue=" . $this->GetQname()."&amp;action=show"; 
2592 f5881023 Ermal Lu?i
		$tree .= "\" ";
2593
		$tmpvalue = trim($this->GetDefault());
2594
		if (!empty($tmpvalue))
2595
			$tree .= " class=\"navlnk\"";
2596
		$tree .= " >" . $this->GetQname() . "</a>";
2597
		$tree .= "</li>";
2598
		return $tree;
2599 2b5caa0e Ermal Luçi
	}
2600 ce0117f7 Colin Fleming
2601 70b139a3 Chris Buechler
	/* Even this should take children into consideration */
2602 9d0b0635 Ermal
	function build_rules(&$default = false) {
2603 2b5caa0e Ermal Luçi
		$pfq_rule = "queue ". $this->qname;
2604
		if ($this->GetInterface())
2605 85a5da13 Ermal Luçi
			$pfq_rule .= " on ".get_real_interface($this->GetInterface());
2606 2b5caa0e Ermal Luçi
		if ($this->GetBandwidth() && $this->GetBwscale())
2607
			$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
2608 f5881023 Ermal Lu?i
		$tmpvalue = trim($this->GetQpriority());
2609
		if (!empty($tmpvalue))
2610 2b5caa0e Ermal Luçi
			$pfq_rule .= " priority " . $this->GetQpriority();
2611 f5881023 Ermal Lu?i
		$tmpvalue = trim($this->GetQlimit());
2612
		if (!empty($tmpvalue))
2613 2b5caa0e Ermal Luçi
			$pfq_rule .= " qlimit " . $this->GetQlimit();
2614
		if ($this->GetDefault() || $this->GetRed() || $this->GetRio() 
2615 8edaa92c Ermal
			|| $this->GetEcn() || $this->GetBuckets() || $this->GetHogs() || $this->GetCodel()) {
2616 ae3d3adb Ermal Luçi
			$pfq_rule .= " fairq ( ";
2617 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetRed());
2618
			if (!empty($tmpvalue)) {
2619 2b5caa0e Ermal Luçi
				$comma = 1;
2620
				$pfq_rule .= " red ";
2621
			}
2622 8edaa92c Ermal
			$tmpvalue = trim($this->GetCodel());
2623
			if (!empty($tmpvalue)) {
2624
				$comma = 1;
2625
				$pfq_rule .= " codel ";
2626
			}
2627 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetRio());
2628
			if (!empty($tmpvalue)) {
2629 2b5caa0e Ermal Luçi
				if ($comma) 
2630
					$pfq_rule .= " ,";
2631
				$comma = 1;
2632
				$pfq_rule .= " rio ";
2633
			}
2634 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetEcn());
2635
			if (!empty($tmpvalue)) {
2636 2b5caa0e Ermal Luçi
				if ($comma) 
2637
					$pfq_rule .= " ,";
2638
				$comma = 1;
2639
				$pfq_rule .= " ecn ";
2640
			}
2641 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetDefault());
2642
			if (!empty($tmpvalue)) {
2643 2b5caa0e Ermal Luçi
				if ($comma)
2644
					$pfq_rule .= " ,";
2645
				$comma = 1;
2646
				$pfq_rule .= " default ";
2647 ef8fca71 Ermal
				$default = true;
2648 2b5caa0e Ermal Luçi
			}
2649 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetBuckets());
2650
			if (!empty($tmpvalue)) {
2651 2b5caa0e Ermal Luçi
				if ($comma)
2652
					$pfq_rule .= ", ";
2653
				$pfq_rule .= " buckets " . $this->GetBuckets() . " ";
2654
			}
2655 f5881023 Ermal Lu?i
			$tmpvalue = trim($this->GetHogs());
2656
			if (!empty($tmpvalue)) {
2657 2b5caa0e Ermal Luçi
				if ($comma)
2658
					$pfq_rule .= ", ";
2659
				$pfq_rule .= " hogs " . $this->GetHogs() . " ";
2660
			}
2661
				$pfq_rule .= " ) ";
2662
		} 
2663
2664
		$pfq_rule .= " \n";
2665
		return $pfq_rule;
2666
	}
2667
2668
	function build_form() {
2669 f5e511d3 Ermal
		$form = parent::build_form();
2670
		$form .= "<tr>";
2671 7da5315d Colin Fleming
		$form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Bandwidth") . "</td>";
2672 2b5caa0e Ermal Luçi
		$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
2673
		if ($this->GetBandwidth() > 0)
2674 f5881023 Ermal Lu?i
			$form .= htmlspecialchars($this->GetBandwidth());
2675 6f1bcc36 Colin Fleming
		$form .= "\" />";
2676 2b5caa0e Ermal Luçi
		$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
2677
		$form .= "<option value=\"Gb\"";
2678
		if ($this->GetBwscale() == "Gb")
2679 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2680 18efed8b Carlos Eduardo Ramos
		$form .= ">" . gettext("Gbit/s") . "</option>";
2681 2b5caa0e Ermal Luçi
		$form .= "<option value=\"Mb\"";
2682
		if ($this->GetBwscale() == "Mb")
2683 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2684 18efed8b Carlos Eduardo Ramos
		$form .= ">" . gettext("Mbit/s") . "</option>";
2685 2b5caa0e Ermal Luçi
		$form .= "<option value=\"Kb\"";
2686
		if ($this->GetBwscale() == "Kb")
2687 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2688 18efed8b Carlos Eduardo Ramos
		$form .= ">" . gettext("Kbit/s") . "</option>";
2689 10c526e4 Darren Embry
		$form .= "<option value=\"b\"";
2690 2b5caa0e Ermal Luçi
		if ($this->GetBwscale() == "b")
2691 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2692 18efed8b Carlos Eduardo Ramos
		$form .= ">" . gettext("Bit/s") . "</option>";
2693 2b5caa0e Ermal Luçi
		$form .= "<option value=\"%\"";
2694
		if ($this->GetBwscale() == "%")
2695 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
2696 2b5caa0e Ermal Luçi
		$form .= ">%</option>";
2697 0fa05f45 Colin Fleming
		$form .= "</select> <br/>";
2698 dbaf21d4 Renato Botelho
		$form .= "<span class=\"vexpl\">" . gettext("Choose the amount of bandwidth for this queue");
2699 2b5caa0e Ermal Luçi
		$form .= "</span></td></tr>";
2700 dbaf21d4 Renato Botelho
		$form .= "<tr><td class=\"vncellreq\">" . gettext("Scheduler specific options") . "</td>";
2701 ae3d3adb Ermal Luçi
		$form .= "<td class=\"vtable\"><table><tr><td>";
2702
		$form .= "<input id=\"buckets\" name=\"buckets\" value=\"";
2703 f5881023 Ermal Lu?i
		$tmpvalue = trim($this->GetBuckets());
2704
		if(!empty($tmpvalue)) 
2705
			$form .=  $this->GetBuckets();
2706 6f1bcc36 Colin Fleming
		$form .= "\" /> " . gettext("Number of buckets available.") . "<br/></td></tr>";
2707 ae3d3adb Ermal Luçi
		$form .= "<tr><td class=\"vtable\"><input id=\"hogs\" name=\"hogs\" value=\"";
2708 f5881023 Ermal Lu?i
		$tmpvalue = trim($this->GetHogs());
2709
		if(!empty($tmpvalue)) 
2710
			$form .=  $this->GetHogs();
2711 6f1bcc36 Colin Fleming
		$form .= "\" /> " . gettext("Bandwidth limit for hosts to not saturate link.") . "<br/></td></tr>";
2712 ae3d3adb Ermal Luçi
		$form .= "</table></td></tr>";
2713 2b5caa0e Ermal Luçi
		return $form;
2714
	}
2715
2716
	function update_altq_queue_data(&$data) { 
2717
		$this->ReadConfig($data);
2718
	}
2719
2720
	function wconfig() {
2721
		$cflink =& get_reference_to_me_in_config($this->GetLink());
2722
		if (!is_array($cflink))
2723
			$cflink = array();
2724
		$cflink['interface'] = $this->GetInterface();
2725 f5881023 Ermal Lu?i
		$cflink['qlimit'] = trim($this->GetQlimit());
2726
		if (empty($cflink['qlimit']))
2727
			unset($cflink['qlimit']);
2728
		$cflink['priority'] = trim($this->GetQpriority());
2729
		if (empty($cflink['priority']))
2730
			unset($cflink['priority']);
2731 2b5caa0e Ermal Luçi
		$cflink['name'] = $this->GetQname();
2732 f5881023 Ermal Lu?i
		$cflink['description'] = trim($this->GetDescription());
2733
		if (empty($cflink['description']))
2734
			unset($cflink['description']);
2735 2b5caa0e Ermal Luçi
		$cflink['bandwidth'] = $this->GetBandwidth();
2736
		$cflink['bandwidthtype'] = $this->GetBwscale();
2737
		$cflink['enabled'] = $this->GetEnabled();
2738 f5881023 Ermal Lu?i
		if (empty($cflink['enabled']))
2739
			unset($cflink['enabled']);
2740
		$cflink['default'] = trim($this->GetDefault());
2741
		if (empty($cflink['default']))
2742
			unset($cflink['default']);
2743
		$cflink['red'] = trim($this->GetRed());
2744
		if (empty($cflink['red']))
2745
			unset($cflink['red']);
2746
		$cflink['rio'] = trim($this->GetRio());
2747
		if (empty($cflink['rio']))
2748
			unset($cflink['rio']);
2749
		$cflink['ecn'] = trim($this->GetEcn());
2750
		if (empty($cflink['ecn']))
2751
			unset($cflink['ecn']);
2752 ff8affb4 Richard Connon
		$cflink['codel'] = trim($this->GetCodel());
2753
		if (empty($cflink['codel']))
2754
			unset($cflink['codel']);
2755 f5881023 Ermal Lu?i
		$cflink['buckets'] = trim($this->GetBuckets());
2756
		if (empty($cflink['buckets']))
2757
			unset($cflink['buckets']);
2758
		$cflink['hogs'] = trim($this->GetHogs());
2759
		if (empty($cflink['hogs']))
2760
			unset($cflink['hogs']);
2761 2b5caa0e Ermal Luçi
	}
2762
}
2763 061f78b1 Bill Marquette
2764
2765 c25a6b6a Ermal Luçi
/*
2766 0dc7b4aa Ermal
 * dummynet(4) wrappers.
2767 c25a6b6a Ermal Luçi
 */
2768
2769
2770
/*
2771
 * List of respective objects!
2772
 */
2773 d62ba478 Ermal Luçi
$dummynet_pipe_list = array();
2774 c25a6b6a Ermal Luçi
2775
class dummynet_class {
2776
        var $qname;
2777 f5881023 Ermal Lu?i
	var $qnumber; /* dummynet(4) uses numbers instead of names; maybe integrate with pf the same as altq does?! */
2778 c25a6b6a Ermal Luçi
        var $qlimit;
2779
        var $description;
2780 f5881023 Ermal Lu?i
	var $qenabled;
2781
	var $link;
2782
	var $qparent; /* link to upper class so we do things easily on WF2Q+ rule creation */
2783 c25a6b6a Ermal Luçi
        var $plr;
2784
2785
        var $buckets;
2786
        /* mask parameters */
2787
        var $mask;
2788
        var $noerror;
2789 2d46e1e4 Jean Cyr
        
2790 70b139a3 Chris Buechler
        /* Accessor functions */
2791 c25a6b6a Ermal Luçi
        function SetLink($link) {
2792
                $this->link = $link;
2793
        }
2794
        function GetLink() {
2795
                return $this->link;
2796
        }
2797 0b4e7542 Jean Cyr
	function GetMask() {
2798 8c50a9d8 Jean Cyr
		if (!isset($this->mask["type"]))
2799
			$this->mask["type"] = "none";
2800 f5881023 Ermal Lu?i
		return $this->mask;
2801
	}
2802
	function SetMask($mask) {
2803
		$this->mask = $mask;
2804
	}
2805
	function &GetParent() {
2806
		return $this->qparent;
2807
	}
2808
	function SetParent(&$parent) {
2809
		$this->qparent = &$parent;
2810
	}
2811 c25a6b6a Ermal Luçi
        function GetEnabled() {
2812
                return $this->qenabled;
2813
        }
2814
        function SetEnabled($value) {
2815
                $this->qenabled = $value;
2816
        }
2817 f5881023 Ermal Lu?i
	function CanHaveChildren() {
2818
		return false;
2819 c25a6b6a Ermal Luçi
        }
2820 f5881023 Ermal Lu?i
	function CanBeDeleted() {
2821 c25a6b6a Ermal Luçi
                return true;
2822
        }
2823
        function GetQname() {
2824
                return $this->qname;
2825
        }
2826
        function SetQname($name) {
2827
                $this->qname = trim($name);
2828
        }
2829
        function GetQlimit() {
2830
                return $this->qlimit;
2831
        }
2832
        function SetQlimit($limit) {
2833
               	$this->qlimit = $limit;
2834
        }
2835
        function GetDescription() {
2836
                return $this->description;
2837
        }
2838
        function SetDescription($str) {
2839 da0ce7ee Chris Buechler
                $this->description = trim($str);
2840 c25a6b6a Ermal Luçi
        }
2841
        function GetFirstime() {
2842
                return $this->firsttime;
2843
        }
2844
        function SetFirsttime($number) {
2845
                $this->firsttime = $number;
2846
        }
2847
        function GetBuckets() {
2848
                return $this->buckets;
2849
        }
2850
        function SetBuckets($buckets) {
2851
                $this->buckets = $buckets;
2852
        }
2853 f5881023 Ermal Lu?i
	function SetNumber($number) {
2854
		$this->qnumber = $number;
2855
	}
2856
	function GetNumber() {
2857
		return $this->qnumber;
2858
	}
2859 c25a6b6a Ermal Luçi
        function GetPlr() {
2860
                return $this->plr;
2861
        }
2862
        function SetPlr($plr) {
2863
                $this->plr = $plr;
2864
        }
2865
2866 8c50a9d8 Jean Cyr
	function build_javascript() {
2867 2d46e1e4 Jean Cyr
		$javascript .= "<script type=\"text/javascript\">\n";
2868 8c50a9d8 Jean Cyr
		$javascript .= "//<![CDATA[\n";
2869 2d46e1e4 Jean Cyr
		$javascript .= "function enable_maskbits(enable_over) {\n";
2870
		$javascript .= "var e = document.getElementById(\"mask\");\n";
2871
		$javascript .= "if ((e.options[e.selectedIndex].text == \"none\") || enable_over) {\n";
2872 8c50a9d8 Jean Cyr
		$javascript .= "document.iform.maskbits.disabled = 1;\n";
2873
		$javascript .= "document.iform.maskbits.value = \"\";\n";
2874 2fbefad6 Jean Cyr
		$javascript .= "document.iform.maskbitsv6.disabled = 1;\n";
2875
		$javascript .= "document.iform.maskbitsv6.value = \"\";\n";
2876 2d46e1e4 Jean Cyr
		$javascript .= "} else {\n";
2877 8c50a9d8 Jean Cyr
		$javascript .= "document.iform.maskbits.disabled = 0;\n";
2878 2fbefad6 Jean Cyr
                $javascript .= "document.iform.maskbitsv6.disabled = 0;\n";
2879 2d46e1e4 Jean Cyr
		$javascript .= "}}\n";
2880 8c50a9d8 Jean Cyr
		$javascript .= "//]]>\n";
2881 2d46e1e4 Jean Cyr
		$javascript .= "</script>\n";
2882 8c50a9d8 Jean Cyr
		return $javascript;
2883
	}
2884 d62ba478 Ermal Luçi
2885 f5881023 Ermal Lu?i
	function validate_input($data, &$input_errors) {
2886
		$reqdfields[] = "bandwidth";
2887 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidth");
2888 b48e2e6b Ermal
		$reqdfields[] = "burst";
2889
		$reqdfieldsn[] = gettext("Burst");
2890 f5881023 Ermal Lu?i
		$reqdfields[] = "bandwidthtype";
2891 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Bandwidthtype");
2892 6be14e38 Ermal
		$reqdfields[] = "newname";
2893 dbaf21d4 Renato Botelho
		$reqdfieldsn[] = gettext("Name");
2894 ce0117f7 Colin Fleming
2895 f5881023 Ermal Lu?i
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
2896
2897
		if ($data['plr'] && ((!is_numeric($data['plr'])) ||
2898 b7d6c7f6 Ermal
			($data['plr'] < 0 && $data['plr'] > 1))) 
2899
				$input_errors[] = gettext("Plr must be a value between 0 and 1.");
2900 f5881023 Ermal Lu?i
		if (($data['buckets'] && (!is_numeric($data['buckets']))) ||
2901 b7d6c7f6 Ermal
			($data['buckets'] < 16 && $data['buckets'] > 65535)) 
2902 dbaf21d4 Renato Botelho
				$input_errors[] = gettext("Buckets must be an integer between 16 and 65535.");
2903 f5881023 Ermal Lu?i
		if ($data['qlimit'] && (!is_numeric($data['qlimit']))) 
2904 152ab4d0 Vinicius Coque
            		$input_errors[] = gettext("Queue limit must be an integer");
2905 6be14e38 Ermal
        	if (!empty($data['newname']) && !preg_match("/^[a-zA-Z0-9_-]+$/", $data['newname']))
2906 152ab4d0 Vinicius Coque
			$input_errors[] = gettext("Queue names must be alphanumeric and _ or - only.");
2907 6be14e38 Ermal
        	if (!empty($data['name']) && !preg_match("/^[a-zA-Z0-9_-]+$/", $data['name']))
2908 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("Queue names must be alphanumeric and _ or - only.");
2909 2d46e1e4 Jean Cyr
                if (isset($data['maskbits']) && ($data['maskbits'] <> ""))
2910 0b4e7542 Jean Cyr
			if ((!is_numeric($data['maskbits'])) || ($data['maskbits'] <= 0) || ($data['maskbits'] > 32))
2911 2d46e1e4 Jean Cyr
				$input_errors[] = gettext("IPV4 bit mask must be blank or numeric value between 1 and 32.");
2912 2fbefad6 Jean Cyr
		if (isset($data['maskbitsv6']) && ($data['maskbitsv6'] <> ""))
2913
			if ((!is_numeric($data['maskbitsv6'])) || ($data['maskbitsv6'] <= 0) || ($data['maskbitsv6'] > 128))
2914
				$input_errors[] = gettext("IPV6 bit mask must be blank or numeric value between 1 and 128.");
2915 2d46e1e4 Jean Cyr
	}
2916
	
2917
	function build_mask_rules(&$pfq_rule) {
2918
		$mask = $this->GetMask();
2919
		if (!empty($mask['type'])) {
2920
			if ($mask['type'] <> 'none')
2921
				$pfq_rule .= " mask";
2922
			switch ($mask['type']) {
2923
			case 'srcaddress':
2924 2fbefad6 Jean Cyr
				if (!empty($mask['bitsv6']) && ($mask['bitsv6'] <> ""))
2925
					$pfq_rule .= " src-ip6 /" . $mask['bitsv6'];
2926
				else
2927
					$pfq_rule .= " src-ip6 /128";
2928 2d46e1e4 Jean Cyr
                                if (!empty($mask['bits']) && ($mask['bits'] <> ""))
2929
                                        $pfq_rule .= sprintf(" src-ip 0x%x", gen_subnet_mask_long($mask['bits']));
2930
                                else
2931
					$pfq_rule .= " src-ip 0xffffffff";
2932
				break;
2933
			case 'dstaddress':
2934 2fbefad6 Jean Cyr
				if (!empty($mask['bitsv6']) && ($mask['bitsv6'] <> ""))
2935
					$pfq_rule .= " dst-ip6 /" . $mask['bitsv6'];
2936
				else
2937
					$pfq_rule .= " dst-ip6 /128";
2938 2d46e1e4 Jean Cyr
                                if (!empty($mask['bits']) && ($mask['bits'] <> ""))
2939
                                        $pfq_rule .= sprintf(" dst-ip 0x%x", gen_subnet_mask_long($mask['bits']));
2940
                                else
2941
					$pfq_rule .= " dst-ip 0xffffffff";
2942
				break;
2943
			default:
2944
				break;
2945
			}
2946
		}            
2947 f5881023 Ermal Lu?i
	}
2948 2d46e1e4 Jean Cyr
        
2949 c25a6b6a Ermal Luçi
}
2950
2951
class dnpipe_class extends dummynet_class {
2952
        var $delay;
2953 c9ba2f8a Ermal
	var $qbandwidth = array();
2954 d62ba478 Ermal Luçi
	var $qbandwidthtype;
2955 c25a6b6a Ermal Luçi
2956
		/* This is here to help on form building and building rules/lists */
2957
        var $subqueues = array();
2958
2959 70b139a3 Chris Buechler
	function CanHaveChildren() {
2960 c25a6b6a Ermal Luçi
	        return true;
2961
        }
2962 d62ba478 Ermal Luçi
	function SetDelay($delay) {
2963
		$this->delay = $delay;
2964
	}
2965
	function GetDelay() {
2966
		return $this->delay;
2967
	}
2968
	function delete_queue() {
2969
		cleanup_dnqueue_from_rules($this->GetQname());
2970
		foreach ($this->subqueues as $q)
2971
			$q->delete_queue();
2972
		unset_dn_object_by_reference($this->GetLink());
2973 3f115d0e Ermal
		mwexec("/sbin/ipfw pipe delete " . $this->GetNumber());
2974 c25a6b6a Ermal Luçi
        }
2975
        function GetBandwidth() {
2976
                return $this->qbandwidth;
2977
        }
2978
        function SetBandwidth($bandwidth) {
2979
                $this->qbandwidth = $bandwidth;
2980
        }
2981 b48e2e6b Ermal
		function GetBurst() {
2982
				return $this->qburst;
2983
		}
2984
		function SetBurst($burst) {
2985
				$this->qburst = $burst;
2986
		}
2987 c25a6b6a Ermal Luçi
2988 d62ba478 Ermal Luçi
	function &add_queue($interface, &$queue, &$path, &$input_errors) {
2989 c25a6b6a Ermal Luçi
2990 d62ba478 Ermal Luçi
		if (!is_array($this->subqueues))
2991
			$this->subqueues = array();
2992 ce0117f7 Colin Fleming
2993 62150088 Ermal Lu?i
		$q =& new dnqueue_class();
2994 d62ba478 Ermal Luçi
		$q->SetLink($path);
2995
		$q->SetEnabled("on");
2996
		$q->SetPipe($this->GetQname());
2997
		$q->SetParent(&$this);
2998
		$q->ReadConfig($queue);
2999
		$q->validate_input($queue, $input_errors);
3000 00ca3fb1 Ermal
		if (count($input_errors)) {
3001
			log_error("SHAPER: could not create queue " . $q->GetQname() . " on interface {$interface} because: " . print_r($input_errors, true));
3002 d62ba478 Ermal Luçi
			return $q;
3003 00ca3fb1 Ermal
		}
3004 85a236e9 Ermal
		$number = dnqueue_find_nextnumber();
3005
		$q->SetNumber($number);
3006 d62ba478 Ermal Luçi
		$this->subqueues[$q->GetQname()] = &$q;
3007
            
3008
		return $q;
3009
	}
3010 c25a6b6a Ermal Luçi
3011 309ffde9 Ermal Luçi
	function &get_queue_list($q = null) {
3012 d62ba478 Ermal Luçi
		$qlist = array();
3013 c25a6b6a Ermal Luçi
3014 64c7753b Ermal Luçi
		$qlist[$this->GetQname()] = $this->GetNumber();
3015 d62ba478 Ermal Luçi
		if (is_array($this->subqueues)) {
3016
			foreach ($this->subqueues as $queue)
3017
				$queue->get_queue_list(&$qlist);
3018 c25a6b6a Ermal Luçi
		}
3019 d62ba478 Ermal Luçi
		return $qlist;
3020
	}
3021 ce0117f7 Colin Fleming
3022 c25a6b6a Ermal Luçi
        /*
3023 70b139a3 Chris Buechler
         * Should search even its children
3024 c25a6b6a Ermal Luçi
         */
3025
        function &find_queue($pipe, $qname) {
3026
                if ($qname == $this->GetQname()) 
3027
                        return $this;
3028
               	foreach ($this->subqueues as $q) {
3029
                       	$result =& $q->find_queue("", $qname);
3030
						if ($result)
3031
                       	        return $result;
3032
               	}
3033
        }
3034
3035 d62ba478 Ermal Luçi
	function &find_parentqueue($pipe, $qname) {
3036
		return NULL;
3037
       	}
3038 c25a6b6a Ermal Luçi
3039 d62ba478 Ermal Luçi
	function validate_input($data, &$input_errors) {
3040
		parent::validate_input($data, $input_errors);
3041 c25a6b6a Ermal Luçi
3042 c9ba2f8a Ermal
		$schedule = 0;
3043
		$schedulenone = 0;
3044
		$entries = 0;
3045
		for ($i = 0; $i < 30; $i++) {
3046
			if (!empty($data["bwsched{$i}"])) {
3047
				if ($data["bwsched{$i}"] != "none")
3048
					$schedule++;
3049
				else
3050
					$schedulenone++;
3051
			}
3052
			if (!empty($data["bandwidth{$i}"])) {
3053
				if (!is_numeric($data["bandwidth{$i}"]))
3054
					$input_errors[] = sprintf(gettext("Bandwidth for schedule %s must be an integer."), $data["bwsched{$i}"]);
3055 9880a11d Jean Cyr
				else if (($data["burst{$i}"] != "") && (!is_numeric($data["burst{$i}"])))
3056 b48e2e6b Ermal
					$input_errors[] = sprintf(gettext("Burst for schedule %s must be an integer."), $data["bwsched{$i}"]);
3057 c9ba2f8a Ermal
				else
3058
					$entries++;
3059
			}
3060
		}
3061
		if ($schedule == 0 && $entries > 1)
3062
			$input_errors[] = gettext("You need to specify a schedule for every additional entry");
3063
		if ($schedulenone > 0 && $entries > 1)
3064
			$input_errors[] = gettext("If more than one bandwidth configured all schedules need to be selected");
3065
		if ($entries == 0)
3066
			$input_errors[] = gettext("At least one bw specification is necessary");
3067 d62ba478 Ermal Luçi
		if ($data['delay'] && (!is_numeric($data['delay'])))
3068 dbaf21d4 Renato Botelho
			$input_errors[] = gettext("Delay must be an integer.");
3069
	}
3070 c25a6b6a Ermal Luçi
3071 d62ba478 Ermal Luçi
	function ReadConfig(&$q) {
3072 1cbe86f0 Ermal
		if (!empty($q['name']) && !empty($q['newname']) && $q['name'] != $q['newname']) {
3073
			$this->SetQname($q['newname']);
3074
		} else if (!empty($q['newname'])) {
3075
			$this->SetQname($q['newname']);
3076
		} else {
3077
			$this->SetQname($q['name']);
3078
		}
3079 d62ba478 Ermal Luçi
		$this->SetNumber($q['number']);
3080 c9ba2f8a Ermal
3081
		if (!empty($_POST)) {
3082
			$bandwidth = array();
3083
			for ($i = 0; $i < 30; $i++) {
3084
				if (isset($q["bandwidth{$i}"]) && $q["bandwidth{$i}"] <> "") { 
3085
					$bw = array();
3086
					$bw['bw'] = $q["bandwidth{$i}"];
3087 b48e2e6b Ermal
					$bw['burst'] = $q["burst{$i}"];
3088 c9ba2f8a Ermal
					if (isset($q["bwtype{$i}"]) && $q["bwtype{$i}"])
3089
						$bw['bwscale'] = $q["bwtype{$i}"];
3090
					if (isset($q["bwsched{$i}"]) && $q["bwsched{$i}"])
3091
						$bw['bwsched'] = $q["bwsched{$i}"];
3092
					$bandwidth[] = $bw;
3093
				}
3094
			}
3095
			$this->SetBandwidth($bandwidth);
3096 d62ba478 Ermal Luçi
		}
3097 b48e2e6b Ermal
		
3098
		if (is_array($q['bandwidth']) && is_array($q['bandwidth']['item'])) {
3099 c9ba2f8a Ermal
			$this->SetBandwidth($q['bandwidth']['item']);
3100 b48e2e6b Ermal
			$this->SetBurst($q['burst']['item']);
3101
		}
3102
			
3103 d62ba478 Ermal Luçi
		if (isset($q['qlimit']) && $q['qlimit'] <> "")
3104
              		$this->SetQlimit($q['qlimit']);
3105 c2461a56 Ermal
		else
3106
              		$this->SetQlimit("");
3107 d62ba478 Ermal Luçi
		if (isset($q['mask']) && $q['mask'] <> "")
3108 0b4e7542 Jean Cyr
			$masktype = $q['mask'];
3109
		else
3110
			$masktype = "";
3111
		if (isset($q['maskbits']) && $q['maskbits'] <> "")
3112
			$maskbits = $q['maskbits'];
3113 c2461a56 Ermal
		else
3114 0b4e7542 Jean Cyr
			$maskbits = "";
3115 2d46e1e4 Jean Cyr
		if (isset($q['maskbitsv6']) && $q['maskbitsv6'] <> "")
3116
			$maskbitsv6 = $q['maskbitsv6'];
3117
		else
3118
			$maskbitsv6 = "";
3119
		$this->SetMask(array("type" => $masktype, "bits" => $maskbits, "bitsv6" => $maskbitsv6));
3120 d62ba478 Ermal Luçi
		if (isset($q['buckets']) && $q['buckets'] <> "")
3121
              		$this->SetBuckets($q['buckets']);
3122 c2461a56 Ermal
		else
3123
              		$this->SetBuckets("");
3124 d62ba478 Ermal Luçi
            	if (isset($q['plr']) && $q['plr'] <> "")
3125
            		$this->SetPlr($q['plr']);
3126 c2461a56 Ermal
		else
3127
            		$this->SetPlr("");
3128 d62ba478 Ermal Luçi
		if (isset($q['delay']) && $q['delay'] <> "")
3129
            		$this->SetDelay($q['delay']);
3130 c2461a56 Ermal
		else
3131
			$this->SetDelay(0);
3132 d62ba478 Ermal Luçi
            	if (isset($q['description']) && $q['description'] <> "")
3133
			$this->SetDescription($q['description']);
3134 c2461a56 Ermal
		else
3135
			$this->SetDescription("");
3136 d62ba478 Ermal Luçi
		$this->SetEnabled($q['enabled']);
3137 c25a6b6a Ermal Luçi
3138
        }
3139
3140 d62ba478 Ermal Luçi
	function build_tree() {
3141 7da5315d Colin Fleming
		$tree = " <li><a href=\"firewall_shaper_vinterface.php?pipe=" . $this->GetQname() ."&amp;queue=".$this->GetQname() ."&amp;action=show\">"; 
3142 d62ba478 Ermal Luçi
		$tree .= $this->GetQname() . "</a>";
3143
		if (is_array($this->subqueues)) {
3144
			$tree .= "<ul>";
3145
			foreach ($this->subqueues as $q)  {
3146
				$tree .= $q->build_tree();
3147
			}	
3148
			$tree .= "</ul>";
3149 c25a6b6a Ermal Luçi
		}
3150 d62ba478 Ermal Luçi
		$tree .= "</li>";
3151 ce0117f7 Colin Fleming
3152 d62ba478 Ermal Luçi
		return $tree;
3153
	}
3154 c25a6b6a Ermal Luçi
3155
        function build_rules() {
3156 c9ba2f8a Ermal
		global $config, $time_based_rules;
3157
3158 8cb1c6e3 Ermal Luçi
		if ($this->GetEnabled() == "")
3159
			return;
3160
3161 e7ccf2a5 Ermal
		$pfq_rule = "\npipe ". $this->GetNumber() . " config ";
3162 fa29a6f0 Ermal
		$found = false;
3163 c9ba2f8a Ermal
		$bandwidth = $this->GetBandwidth();
3164
		if (is_array($bandwidth)) {
3165
			foreach ($bandwidth as $bw) {
3166 fbfed5ba Ermal
				if ($bw['bwsched'] != "none") {
3167 c9ba2f8a Ermal
					$time_based_rules = true;
3168 2ed21904 Ermal
					if (is_array($config['schedules']) && is_array($config['schedules']['schedule'])) {
3169 d96b96b9 Ermal
						foreach ($config['schedules']['schedule'] as $schedule) {
3170
							if ($bw['bwsched'] == $schedule['name']) {
3171
								if (filter_get_time_based_rule_status($schedule)) {
3172
									$pfq_rule .= " bw ".trim($bw['bw']).$bw['bwscale'];
3173 9880a11d Jean Cyr
									if (is_numeric($bw['burst']) && ($bw['burst'] > 0))
3174 11421996 jim-p
										$pfq_rule .= " burst ".trim($bw['burst']).$bw['bwscale'];
3175 fa29a6f0 Ermal
									$found = true;
3176 d96b96b9 Ermal
									break;
3177
								}
3178 c9ba2f8a Ermal
							}
3179
						}
3180 0b3a76ca Ermal
					} else {
3181 fa29a6f0 Ermal
						$pfq_rule .= " bw 0";
3182 02593e37 Ermal Luçi
						$found = true;
3183 0b3a76ca Ermal
						break;
3184
					}
3185 ec091c89 Ermal
				} else {
3186 c9ba2f8a Ermal
					$pfq_rule .= " bw ".trim($bw['bw']).$bw['bwscale'];
3187 9880a11d Jean Cyr
					if (is_numeric($bw['burst']) && ($bw['burst'] > 0))
3188 11421996 jim-p
						$pfq_rule .= " burst ".trim($bw['burst']).$bw['bwscale'];
3189 02593e37 Ermal Luçi
					$found = true;
3190 ec091c89 Ermal
					break;
3191
				}
3192 c9ba2f8a Ermal
			}
3193 fa29a6f0 Ermal
			if ($found == false)
3194
				$pfq_rule .= " bw 0";
3195 ec091c89 Ermal
		} else
3196
			$pfq_rule .= " bw 0";
3197 c9ba2f8a Ermal
3198 d62ba478 Ermal Luçi
		if ($this->GetQlimit())
3199 b48e2e6b Ermal
			$pfq_rule .= " queue " . $this->GetQlimit();
3200 d62ba478 Ermal Luçi
		if ($this->GetPlr())
3201
			$pfq_rule .= " plr " . $this->GetPlr();
3202
		if ($this->GetBuckets())
3203
			$pfq_rule .= " buckets " . $this->GetBuckets();
3204
		if ($this->GetDelay())
3205
			$pfq_rule .= " delay " . $this->GetDelay();
3206 2d46e1e4 Jean Cyr
		$this->build_mask_rules($pfq_rule);
3207 d62ba478 Ermal Luçi
3208 f7f33eb3 Ermal
		$pfq_rule .= "\n";
3209 f5130e64 Ermal
3210
		if (!empty($this->subqueues) && count($this->subqueues) > 0) {
3211
			foreach ($this->subqueues as $q)
3212
			$pfq_rule .= $q->build_rules();
3213
		}
3214 d62ba478 Ermal Luçi
		$pfq_rule .= " \n";
3215 c25a6b6a Ermal Luçi
3216 d62ba478 Ermal Luçi
		return $pfq_rule;
3217 c25a6b6a Ermal Luçi
        }
3218
3219 d62ba478 Ermal Luçi
	function update_dn_data(&$data) { 
3220
		$this->ReadConfig($data);
3221
	}
3222 c25a6b6a Ermal Luçi
3223 c9ba2f8a Ermal
	function build_javascript() {
3224
		global $g, $config;
3225
3226 8c50a9d8 Jean Cyr
		$javasr = parent::build_javascript();
3227
		
3228 c9ba2f8a Ermal
		//build list of schedules
3229
		$schedules = "<option value='none'>none</option>";
3230
		if (is_array($config['schedules']) && is_array($config['schedules']['schedule'])) {
3231
			foreach ($config['schedules']['schedule'] as $schedule) {
3232
				if ($schedule['name'] <> "")
3233
					$schedules .= "<option value='{$schedule['name']}'>{$schedule['name']}</option>";
3234
			}
3235
		}
3236
		$bwopt = "";
3237
		foreach (array("Kb" => "Kbit/s", "Mb" => "Mbit/s", "Gb" => "Gbit/s", "b" => "Bit/s") as $bwidx => $bw)
3238
			$bwopt .= "<option value='{$bwidx}'>{$bw}</option>";
3239
3240 8c50a9d8 Jean Cyr
		$javasr .= <<<EOD
3241 7da5315d Colin Fleming
<script type='text/javascript'>
3242 0fa05f45 Colin Fleming
//<![CDATA[
3243 c9ba2f8a Ermal
var addBwRowTo = (function() {
3244
	return (function (tableId) {
3245
	var d, tbody, tr, td;
3246
	d = document;
3247
	tbody = d.getElementById(tableId).getElementsByTagName("tbody").item(0);
3248
	tr = d.createElement("tr");
3249
	td = d.createElement("td");
3250 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 + "' />";
3251 c9ba2f8a Ermal
	tr.appendChild(td);
3252
	td = d.createElement("td");
3253 b48e2e6b 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 + "' />";
3254
	tr.appendChild(td);
3255
	td = d.createElement("td");
3256 6f1bcc36 Colin Fleming
	td.innerHTML="<input type='hidden' value='" + totalrows +"' name='bwtype_row-" + totalrows + "' /><select class='formselect' name='bwtype" + totalrows + "'>{$bwopt}</select>";
3257 c9ba2f8a Ermal
	tr.appendChild(td);
3258
	td = d.createElement("td");
3259 6f1bcc36 Colin Fleming
	td.innerHTML="<input type='hidden' value='" + totalrows +"' name='bwsched_row-" + totalrows + "' /><select class='formselect' name='bwsched" + totalrows + "'>{$schedules}</select>";
3260 c9ba2f8a Ermal
	tr.appendChild(td);
3261
	td = d.createElement("td");
3262
	td.rowSpan = "1";
3263 6f1bcc36 Colin Fleming
	td.innerHTML = '<a onclick="removeBwRow(this); return false;" href="#"><img border="0" src="/themes/{$g['theme']}/images/icons/icon_x.gif" alt="remove" /></a>';
3264 c9ba2f8a Ermal
	tr.appendChild(td);
3265
	tbody.appendChild(tr);
3266
	totalrows++;
3267
	});
3268
})();
3269
3270
function removeBwRow(el) {
3271
	var cel;
3272
	while (el && el.nodeName.toLowerCase() != "tr")
3273
	    el = el.parentNode;
3274
		if (el && el.parentNode) {
3275
			cel = el.getElementsByTagName("td").item(0);
3276
			el.parentNode.removeChild(el);
3277
		}
3278
}
3279 0fa05f45 Colin Fleming
//]]>
3280 c9ba2f8a Ermal
</script>
3281
3282
EOD;
3283
3284
	       return $javasr;
3285
	}
3286
3287 c25a6b6a Ermal Luçi
        function build_form() { 
3288 c9ba2f8a Ermal
		global $g, $config;
3289
3290
		//build list of schedules
3291
		$schedules = array();
3292
		$schedules[] = "none";//leave none to leave rule enabled all the time
3293
		if (is_array($config['schedules']) && is_array($config['schedules']['schedule'])) {
3294
			foreach ($config['schedules']['schedule'] as $schedule) {
3295
				if ($schedule['name'] <> "")
3296
					$schedules[] = $schedule['name'];
3297
			}
3298
		}
3299
3300 7da5315d Colin Fleming
		$form = "<tr><td valign=\"middle\" class=\"vncellreq\"><br/>";
3301 9d3d8d00 Vinicius Coque
                $form .= gettext("Enable");
3302 34a3694b Ermal
                $form .= "</td><td class=\"vncellreq\">";
3303
                $form .= " <input type=\"checkbox\" id=\"enabled\" name=\"enabled\" value=\"on\"";
3304
                if ($this->GetEnabled() == "on")
3305 ce0117f7 Colin Fleming
                        $form .=  " checked=\"checked\"";
3306 6f1bcc36 Colin Fleming
                $form .= " /><span class=\"vexpl\"> " . gettext("Enable limiter and its children") . "</span>";
3307 34a3694b Ermal
                $form .= "</td></tr>";
3308 7da5315d Colin Fleming
		$form .= "<tr><td valign=\"middle\" class=\"vncellreq\"><br/><span class=\"vexpl\">" . gettext("Name") . "</span></td>";
3309 c25a6b6a Ermal Luçi
		$form .= "<td class=\"vncellreq\">";
3310 1cbe86f0 Ermal
		$form .= "<input type=\"text\" id=\"newname\" name=\"newname\" value=\"";
3311 6f1bcc36 Colin Fleming
		$form .= $this->GetQname()."\" />";
3312 1cbe86f0 Ermal
		$form .= "<input type=\"hidden\" id=\"name\" name=\"name\" value=\"";
3313 6f1bcc36 Colin Fleming
		$form .= $this->GetQname()."\" />";
3314 85a236e9 Ermal
		if ($this->GetNumber() > 0) {
3315
			$form .= "<input type=\"hidden\" id=\"number\" name=\"number\" value=\"";
3316 6f1bcc36 Colin Fleming
			$form .= $this->GetNumber()."\" />";
3317 85a236e9 Ermal
		}
3318 c25a6b6a Ermal Luçi
		$form .= "</td></tr>";
3319 7da5315d Colin Fleming
		$form .= "<tr><td valign=\"middle\" class=\"vncellreq\">" . gettext("Bandwidth");
3320 c9ba2f8a Ermal
		$bandwidth = $this->GetBandwidth();
3321 c25a6b6a Ermal Luçi
		$form .= "</td><td class=\"vncellreq\">";
3322 c9ba2f8a Ermal
		$form .= "<table id='maintable'>";
3323
		$form .= "<tbody><tr>";
3324 b48e2e6b Ermal
		$form .= "<td width='35%'><div id='onecolumn'>Bandwidth</div></td>";
3325
		$form .= "<td width='35%'><div id='fifthcolumn'>Burst</div></td>";
3326 c9ba2f8a Ermal
		$form .= "<td width='20%'><div id='twocolumn'>Bw type</div></td>";
3327
		$form .= "<td width='35%' ><div id='thirdcolumn'>Schedule</div></td>";
3328
		$form .= "<td width='5%'><div id='fourthcolumn'></div></td>";
3329
		$form .= "</tr>";
3330
		if (is_array($bandwidth)) {
3331
			foreach ($bandwidth as $bwidx => $bw) {
3332
				$form .= "\n<tr><td width='40%'>";
3333 6f1bcc36 Colin Fleming
				$form .= "<input class='formfld unknown' size='10' type=\"text\" id=\"bandwidth{$bwidx}\" name=\"bandwidth{$bwidx}\" value=\"{$bw['bw']}\" />";
3334 c9ba2f8a Ermal
				$form .= "</td><td width='20%'>";
3335 b48e2e6b Ermal
				$form .= "<input class='formfld unknown' size='10' type=\"text\" id=\"burst{$bwidx}\" name=\"burst{$bwidx}\" value=\"{$bw['burst']}\" />";
3336
				$form .= "</td><td width='20%'>";
3337 c9ba2f8a Ermal
				$form .= "<select id=\"bwtype{$bwidx}\" name=\"bwtype{$bwidx}\" class=\"formselect\">";
3338
				foreach (array("Kb" => "Kbit/s", "Mb" => "Mbit/s", "Gb" => "Gbit/s", "b" => "Bit/s") as $bwsidx => $bwscale) {
3339
					$form .= "<option value=\"{$bwsidx}\"";
3340
					if ($bw['bwscale'] == $bwsidx)
3341 ce0117f7 Colin Fleming
						$form .= " selected=\"selected\"";
3342 c9ba2f8a Ermal
					$form .= ">{$bwscale}</option>";
3343
				}
3344
				$form .= "</select>";
3345
				$form .= "</td><td width='35%' >";
3346
				$form .= "<select id=\"bwsched{$bwidx}\" name=\"bwsched{$bwidx}\" class=\"formselect\">";
3347
				foreach ($schedules as $schd) {
3348
					$selected = "";
3349
					if ($bw['bwsched'] == $schd)
3350 ce0117f7 Colin Fleming
						$selected = "selected=\"selected\"";
3351 c9ba2f8a Ermal
					$form .= "<option value='{$schd}' {$selected}>{$schd}</option>";
3352
				}
3353
				$form .= "</select>";
3354
				$form .= "</td><td width='5%' >";
3355 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>";
3356 c9ba2f8a Ermal
				$form .= "</td></tr>";
3357
			}
3358
		}
3359
		$form .= "</tbody></table>";
3360
		$form .= "<a onclick=\"javascript:addBwRowTo('maintable'); return false;\" href='#'>";
3361 6f1bcc36 Colin Fleming
		$form .= "<img border='0' src='/themes/{$g['theme']}/images/icons/icon_plus.gif' alt='add' title='" . gettext("add another schedule") . "' /></a>";
3362 a27403c4 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 />";
3363 c25a6b6a Ermal Luçi
		$form .= "</td></tr>";
3364 7da5315d Colin Fleming
		$form .= "<tr><td valign=\"middle\" class=\"vncellreq\">" . gettext("Mask") . "</td>";
3365 2e1abb31 Ermal Luçi
		$form .= "<td class=\"vncellreq\">";
3366 8c50a9d8 Jean Cyr
		$form .= "<select name=\"mask\" id=\"mask\" class=\"formselect\" onchange=\"enable_maskbits();\" >";
3367 2e1abb31 Ermal Luçi
		$form .= "<option value=\"none\"";
3368 0b4e7542 Jean Cyr
		$mask = $this->GetMask();
3369
		if ($mask['type'] == "none")
3370 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
3371 2e1abb31 Ermal Luçi
		$form .= ">none</option>";
3372
		$form .= "<option value=\"srcaddress\"";
3373 0b4e7542 Jean Cyr
		if ($mask['type'] == "srcaddress")
3374 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
3375 dbaf21d4 Renato Botelho
		$form .= ">" . gettext("Source addresses") . "</option>";
3376 2e1abb31 Ermal Luçi
		$form .= "<option value=\"dstaddress\"";
3377 0b4e7542 Jean Cyr
		if ($mask['type'] == "dstaddress")
3378 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
3379 dbaf21d4 Renato Botelho
		$form .= ">" . gettext("Destination addresses") . "</option>";
3380 2e1abb31 Ermal Luçi
		$form .= "</select>";
3381 0fa05f45 Colin Fleming
		$form .= "&nbsp;<br/>";
3382 0b4e7542 Jean Cyr
		$form .= "<span class=\"vexpl\">" . gettext("If 'source' or 'destination' slots is chosen, \n"
3383 dbaf21d4 Renato Botelho
		      .  "a dynamic pipe with the bandwidth, delay, packet loss and queue size given above will \n"
3384
		      .  "be created for each source/destination IP address encountered, \n"
3385
		      .  "respectively. This makes it possible to easily specify bandwidth \n"
3386 0b4e7542 Jean Cyr
		      .  "limits per host.") . "</span><br />";
3387
		$form .= "255.255.255.255/&nbsp;<input type=\"text\" class=\"formfld unknown\" size=\"2\" id=\"maskbits\" name=\"maskbits\" value=\"";
3388 8c50a9d8 Jean Cyr
		if ($mask['type'] <> "none")
3389 0b4e7542 Jean Cyr
		$form .= $mask['bits'];
3390 8c50a9d8 Jean Cyr
		$form .= "\"";
3391
		if ($mask['type'] == "none")
3392
			$form .= " disabled";
3393
		$form .= " />";
3394 2d46e1e4 Jean Cyr
		$form .= "&nbsp; IPV4 mask bits (1-32)<br/>";
3395 2fbefad6 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=\"";
3396
		if ($mask['type'] <> "none")
3397
		$form .= $mask['bitsv6'];
3398
		$form .= "\"";
3399
		if ($mask['type'] == "none")
3400
			$form .= " disabled";
3401
		$form .= " />";
3402
		$form .= "&nbsp; IPV6 mask bits (1-128)<br/>";
3403 0b4e7542 Jean Cyr
		$form .= "<span class=\"vexpl\">" . gettext("If 'source' or 'destination' slots is chosen, \n"
3404
		      .  "leaving the mask bits blank will create one pipe per host. Otherwise specify \n"
3405
		      .  "the number of 'one' bits in the subnet mask used to group multiple hosts \n"
3406
		      .  "per pipe.") . "</span>";
3407 2e1abb31 Ermal Luçi
		$form .= "</td></tr>";
3408 7da5315d Colin Fleming
		$form .= "<tr><td valign=\"middle\" class=\"vncellreq\">" . gettext("Description") . "</td>";
3409 2e1abb31 Ermal Luçi
		$form .= "<td class=\"vncellreq\">";
3410 d8484854 Colin Fleming
		$form .= "<input type=\"text\" class=\"formfld unknown\" size=\"40\" id=\"description\" name=\"description\" value=\"";
3411 2e1abb31 Ermal Luçi
		$form .= $this->GetDescription();
3412 6f1bcc36 Colin Fleming
		$form .= "\" />";
3413 0fa05f45 Colin Fleming
		$form .= "<br/> <span class=\"vexpl\">";
3414 dbaf21d4 Renato Botelho
		$form .= gettext("You may enter a description here for your reference (not parsed).") . "</span>";
3415 2e1abb31 Ermal Luçi
		$form .= "</td></tr>";
3416 d8484854 Colin Fleming
      		$form .= "<tr id=\"sprtable4\">";
3417 2e1abb31 Ermal Luçi
		$form .= "<td></td>";
3418 77dc6894 Ermal Luçi
                $form .= "<td><div id=\"showadvancedboxspr\">";
3419 6f1bcc36 Colin Fleming
                $form .= "<p><input type=\"button\" onclick=\"show_source_port_range()\"";
3420
		$form .= " value=\"" . gettext("Show advanced options") . "\" />";
3421 d8484854 Colin Fleming
                $form .= "</p></div></td></tr>";
3422
                $form .= "<tr style=\"display:none\" id=\"sprtable\">";
3423 77dc6894 Ermal Luçi
3424 7da5315d Colin Fleming
		$form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Delay") . "</td>";
3425
		$form .= "<td valign=\"middle\" class=\"vncellreq\">";
3426 c25a6b6a Ermal Luçi
		$form .= "<input name=\"delay\" type=\"text\" id=\"delay\" size=\"5\" value=\"";
3427 6f1bcc36 Colin Fleming
		$form .= $this->GetDelay() . "\" />";
3428 0fa05f45 Colin Fleming
		$form .= "&nbsp;ms<br/> <span class=\"vexpl\">" . gettext("Hint: in most cases, you "
3429 d8484854 Colin Fleming
			  .  "should specify 0 here (or leave the field empty)") . "</span><br/>";
3430
		$form .= "</td></tr>";
3431
      		$form .= "<tr style=\"display:none\" id=\"sprtable1\">";
3432 7da5315d Colin Fleming
		$form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Packet loss rate") . "</td>";
3433
		$form .= "<td valign=\"middle\" class=\"vncellreq\">";
3434 c25a6b6a Ermal Luçi
		$form .= "<input name=\"plr\" type=\"text\" id=\"plr\" size=\"5\" value=\"";
3435 6f1bcc36 Colin Fleming
		$form .= $this->GetPlr() . "\" />";
3436 0fa05f45 Colin Fleming
		$form .= "&nbsp;<br/> <span class=\"vexpl\">" . gettext("Hint: in most cases, you "
3437 dbaf21d4 Renato Botelho
			  .  "should specify 0 here (or leave the field empty). "
3438
		      .  "A value of 0.001 means one packet in 1000 gets dropped") . "</span>";
3439 c25a6b6a Ermal Luçi
		$form .= "</td></tr>";
3440 d8484854 Colin Fleming
		$form .= "<tr style=\"display:none\" id=\"sprtable2\">";
3441 7da5315d Colin Fleming
		$form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Queue Size") . "</td>";
3442 c25a6b6a Ermal Luçi
		$form .= "<td class=\"vncellreq\">";
3443
		$form .= "<input type=\"text\" id=\"qlimit\" name=\"qlimit\" value=\"";
3444 6f1bcc36 Colin Fleming
		$form .= $this->GetQlimit() . "\" />";
3445 0fa05f45 Colin Fleming
		$form .= "&nbsp;slots<br/>";
3446 dbaf21d4 Renato Botelho
		$form .= "<span class=\"vexpl\">" . gettext("Hint: in most cases, you "
3447
		      .  "should leave the field empty. All packets in this pipe are placed into a fixed-size queue first, "
3448
	              .  "then they are delayed by value specified in the Delay field, and then they "
3449
		      .  "are delivered to their destination.") . "</span>";
3450 ff0189e7 Ermal Luçi
		$form .= "</td></tr>";
3451 d8484854 Colin Fleming
		$form .= "<tr style=\"display:none\" id=\"sprtable5\">";
3452 7da5315d Colin Fleming
                $form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Bucket Size") . "</td>";
3453 1c3fd96b Ermal Luçi
                $form .= "<td class=\"vncellreq\">";
3454
                $form .= "<input type=\"text\" id=\"buckets\" name=\"buckets\" value=\"";
3455 6f1bcc36 Colin Fleming
                $form .= $this->GetBuckets() . "\" />";
3456 0fa05f45 Colin Fleming
                $form .= "&nbsp;slots<br/>";
3457 dbaf21d4 Renato Botelho
                $form .= "<span class=\"vexpl\">" . gettext("Hint: in most cases, you "
3458
                      .  "should leave the field empty. It increases the hash size set.");
3459 d8484854 Colin Fleming
                $form .= "</span></td></tr>";
3460 c25a6b6a Ermal Luçi
3461
		return $form;
3462 ce0117f7 Colin Fleming
3463 c25a6b6a Ermal Luçi
		}
3464
3465 d62ba478 Ermal Luçi
	function wconfig() {
3466
		$cflink =& get_dn_reference_to_me_in_config($this->GetLink());
3467
            	if (!is_array($cflink))
3468
            		$cflink = array();
3469
		$cflink['name'] = $this->GetQname();
3470
		$cflink['number'] = $this->GetNumber();
3471
            	$cflink['qlimit'] = $this->GetQlimit();
3472
            	$cflink['plr'] = $this->GetPlr();
3473
            	$cflink['description'] = $this->GetDescription();
3474 c9ba2f8a Ermal
               
3475
		$bandwidth = $this->GetBandwidth();
3476
		if (is_array($bandwidth)) {
3477
			$cflink['bandwidth'] = array();
3478
			$cflink['bandwidth']['item'] = array();
3479
			foreach ($bandwidth as $bwidx => $bw)
3480
				$cflink['bandwidth']['item'][] = $bw;
3481
		}
3482
3483 d62ba478 Ermal Luçi
		$cflink['enabled'] = $this->GetEnabled();
3484
		$cflink['buckets'] = $this->GetBuckets();
3485 0b4e7542 Jean Cyr
		$mask = $this->GetMask();
3486
		$cflink['mask'] = $mask['type'];
3487
		$cflink['maskbits'] = $mask['bits'];
3488 2fbefad6 Jean Cyr
                $cflink['maskbitsv6'] = $mask['bitsv6'];
3489 d62ba478 Ermal Luçi
		$cflink['delay'] = $this->GetDelay();
3490
	}
3491 c25a6b6a Ermal Luçi
3492
}
3493
3494
class dnqueue_class extends dummynet_class {
3495
        var $pipeparent;
3496
        var $weight;
3497
3498
        function GetWeight() {
3499
                return $this->weight;
3500
        }
3501
        function SetWeight($weight) {
3502
                $this->weight = $weight;
3503
        }
3504 d62ba478 Ermal Luçi
	function GetPipe() {
3505
		return $this->pipeparent;
3506
	}
3507
	function SetPipe($pipe) {
3508
		$this->pipeparent = $pipe;
3509
	}
3510 c25a6b6a Ermal Luçi
3511 d62ba478 Ermal Luçi
	/* Just a stub in case we ever try to call this from the frontend. */
3512
	function &add_queue($interface, &$queue, &$path, &$input_errors) { return; }
3513 c25a6b6a Ermal Luçi
3514 d62ba478 Ermal Luçi
	function delete_queue() {
3515
		cleanup_dnqueue_from_rules($this->GetQname());
3516
		unset_dn_object_by_reference($this->GetLink());
3517 3f115d0e Ermal
		mwexec("/sbin/ipfw queue delete " . $this->GetNumber());
3518 c25a6b6a Ermal Luçi
        }
3519
3520 d62ba478 Ermal Luçi
	function validate_input($data, &$input_errors) {
3521
		parent::validate_input($data, $input_errors);
3522 c25a6b6a Ermal Luçi
3523 d62ba478 Ermal Luçi
		if ($data['weight'] && ((!is_numeric($data['weight'])) ||
3524
			($data['weight'] < 1 && $data['weight'] > 100))) 
3525 dbaf21d4 Renato Botelho
				$input_errors[] = gettext("Weight must be an integer between 1 and 100.");
3526 d62ba478 Ermal Luçi
	}
3527 c25a6b6a Ermal Luçi
3528
        /*
3529 70b139a3 Chris Buechler
         * Should search even its children
3530 c25a6b6a Ermal Luçi
         */
3531
        function &find_queue($pipe, $qname) {
3532
                if ($qname == $this->GetQname()) 
3533 d62ba478 Ermal Luçi
                	return $this;
3534
		else
3535
			return NULL;
3536 c25a6b6a Ermal Luçi
        }
3537
3538 d62ba478 Ermal Luçi
	function &find_parentqueue($pipe, $qname) {
3539
		return $this->qparent;
3540 c25a6b6a Ermal Luçi
        }
3541
3542 309ffde9 Ermal Luçi
        function &get_queue_list(&$qlist) {
3543 146f0fad Ermal
		if ($this->GetEnabled() == "")
3544
			return;
3545 64c7753b Ermal Luçi
        	$qlist[$this->GetQname()] = "?" .$this->GetNumber();
3546 c25a6b6a Ermal Luçi
        }		
3547
3548 d62ba478 Ermal Luçi
	function ReadConfig(&$q) {
3549 1cbe86f0 Ermal
		if (!empty($q['name']) && !empty($q['newname']) && $q['name'] != $q['newname']) {
3550
			$this->SetQname($q['newname']);
3551
		} else if (!empty($q['newname'])) {
3552
			$this->SetQname($q['newname']);
3553
		} else {
3554
			$this->SetQname($q['name']);
3555
		}
3556 d62ba478 Ermal Luçi
		$this->SetNumber($q['number']);
3557
		if (isset($q['qlimit']) && $q['qlimit'] <> "")
3558
       		       	$this->SetQlimit($q['qlimit']);
3559 daacb818 Ermal
		else
3560
       		       	$this->SetQlimit("");
3561 d62ba478 Ermal Luçi
		if (isset($q['mask']) && $q['mask'] <> "")
3562 0b4e7542 Jean Cyr
			$masktype = $q['mask'];
3563 daacb818 Ermal
		else
3564 0b4e7542 Jean Cyr
			$masktype = "";
3565
		if (isset($q['maskbits']) && $q['maskbits'] <> "")
3566
			$maskbits = $q['maskbits'];
3567
		else
3568
			$maskbits = "";
3569 2d46e1e4 Jean Cyr
		if (isset($q['maskbitsv6']) && $q['maskbitsv6'] <> "")
3570
			$maskbitsv6 = $q['maskbitsv6'];
3571
		else
3572
			$maskbitsv6 = "";
3573
		$this->SetMask(array("type" => $masktype, "bits" => $maskbits, "bitsv6" => $maskbitsv6));
3574 d62ba478 Ermal Luçi
       		if (isset($q['weight']) && $q['weight'] <> "")
3575
            		$this->SetWeight($q['weight']);
3576 daacb818 Ermal
		else
3577
            		$this->SetWeight("");
3578 da0ce7ee Chris Buechler
            	if (isset($q['description']) && $q['description'] <> "")
3579 d62ba478 Ermal Luçi
			$this->SetDescription($q['description']);
3580 daacb818 Ermal
		else
3581
			$this->SetDescription("");
3582 d62ba478 Ermal Luçi
		$this->SetEnabled($q['enabled']);
3583 c25a6b6a Ermal Luçi
        }
3584
3585 d62ba478 Ermal Luçi
	function build_tree() {
3586
		$parent =& $this->GetParent();
3587 7da5315d Colin Fleming
		$tree = " <li><a href=\"firewall_shaper_vinterface.php?pipe=" . $parent->GetQname() ."&amp;queue=" . $this->GetQname() ."&amp;action=show\">"; 
3588 d62ba478 Ermal Luçi
		$tree .= $this->GetQname() . "</a>";
3589
		$tree .= "</li>";
3590 ce0117f7 Colin Fleming
3591 d62ba478 Ermal Luçi
		return $tree;
3592
	}
3593 c25a6b6a Ermal Luçi
3594
        function build_rules() {
3595 8cb1c6e3 Ermal Luçi
		if ($this->GetEnabled() == "")
3596
			return; 
3597
3598 d62ba478 Ermal Luçi
		$parent =& $this->GetParent();
3599 f40980ad Ermal
            	$pfq_rule = "queue ". $this->GetNumber() . " config pipe " . $parent->GetNumber();
3600 d62ba478 Ermal Luçi
		if ($this->GetQlimit())
3601 f989a6ef Chris Buechler
                    	$pfq_rule .= " queue " . $this->GetQlimit();
3602 d62ba478 Ermal Luçi
		if ($this->GetWeight())
3603
			$pfq_rule .= " weight " . $this->GetWeight();
3604
		if ($this->GetBuckets())
3605
			$pfq_rule .= " buckets " . $this->GetBuckets();
3606 2d46e1e4 Jean Cyr
		$this->build_mask_rules($pfq_rule);
3607 9b10a6ec Ermal
		$pfq_rule .= "\n";
3608 c25a6b6a Ermal Luçi
3609 d62ba478 Ermal Luçi
		return $pfq_rule;
3610
	}
3611
3612 8c50a9d8 Jean Cyr
        function build_javascript() {
3613
		return parent::build_javascript();
3614
	}
3615
3616
3617 d62ba478 Ermal Luçi
        function build_form() { 
3618 7da5315d Colin Fleming
		$form = "<tr><td valign=\"middle\" class=\"vncellreq\"><br/>";
3619 dbaf21d4 Renato Botelho
                $form .= gettext("Enable/Disable");
3620 34a3694b Ermal
                $form .= "</td><td class=\"vncellreq\">";
3621
                $form .= " <input type=\"checkbox\" id=\"enabled\" name=\"enabled\" value=\"on\"";
3622
                if ($this->GetEnabled() == "on")
3623 ce0117f7 Colin Fleming
                        $form .=  " checked=\"checked\"";
3624 6f1bcc36 Colin Fleming
                $form .= " /><span class=\"vexpl\"> " . gettext("Enable/Disable queue") . "</span>";
3625 34a3694b Ermal
                $form .= "</td></tr>";
3626 7da5315d Colin Fleming
		$form .= "<tr><td valign=\"middle\" class=\"vncellreq\"><br/><span class=\"vexpl\">" . gettext("Name") . "</span></td>";
3627 c25a6b6a Ermal Luçi
		$form .= "<td class=\"vncellreq\">";
3628 1cbe86f0 Ermal
		$form .= "<input type=\"text\" id=\"newname\" name=\"newname\" value=\"";
3629 6f1bcc36 Colin Fleming
		$form .= $this->GetQname()."\" />";
3630 1cbe86f0 Ermal
		$form .= "<input type=\"hidden\" id=\"name\" name=\"name\" value=\"";
3631 6f1bcc36 Colin Fleming
		$form .= $this->GetQname()."\" />";
3632 85a236e9 Ermal
		if ($this->GetNumber() > 0) {
3633
			$form .= "<input type=\"hidden\" id=\"number\" name=\"number\" value=\"";
3634 6f1bcc36 Colin Fleming
			$form .= $this->GetNumber()."\" />";
3635 85a236e9 Ermal
		}
3636 c25a6b6a Ermal Luçi
		$form .= "</td></tr>";
3637 7da5315d Colin Fleming
		$form .= "<tr><td valign=\"middle\" class=\"vncellreq\">" . gettext("Mask") . "</td>";
3638 c25a6b6a Ermal Luçi
		$form .= "<td class=\"vncellreq\">";
3639 8c50a9d8 Jean Cyr
		$form .= "<select name=\"mask\" id=\"mask\" class=\"formselect\" onchange=\"enable_maskbits();\" >";
3640 c25a6b6a Ermal Luçi
		$form .= "<option value=\"none\"";
3641 0b4e7542 Jean Cyr
		$mask = $this->GetMask();
3642
		if ($mask['type'] == "none")
3643 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
3644 dbaf21d4 Renato Botelho
		$form .= ">" . gettext("none") . "</option>";
3645 d62ba478 Ermal Luçi
		$form .= "<option value=\"srcaddress\"";
3646 0b4e7542 Jean Cyr
		if ($mask['type'] == "srcaddress")
3647 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
3648 dbaf21d4 Renato Botelho
		$form .= ">" . gettext("Source addresses") . "</option>";
3649 d62ba478 Ermal Luçi
		$form .= "<option value=\"dstaddress\"";
3650 0b4e7542 Jean Cyr
		if ($mask['type'] == "dstaddress")
3651 ce0117f7 Colin Fleming
			$form .= " selected=\"selected\"";
3652 dbaf21d4 Renato Botelho
		$form .= ">" . gettext("Destination addresses") . "</option>";
3653 c25a6b6a Ermal Luçi
		$form .= "</select>";
3654 0fa05f45 Colin Fleming
		$form .= "&nbsp;slots<br/>";
3655 0b4e7542 Jean Cyr
		$form .= "<span class=\"vexpl\">" . gettext("If 'source' or 'destination' slots is chosen, \n"
3656 dbaf21d4 Renato Botelho
		      .  "a dynamic pipe with the bandwidth, delay, packet loss and queue size given above will \n"
3657
		      .  "be created for each source/destination IP address encountered, \n"
3658
		      .  "respectively. This makes it possible to easily specify bandwidth \n"
3659 0b4e7542 Jean Cyr
		      .  "limits per host.") . "</span><br/>";
3660
		$form .= "255.255.255.255/&nbsp;<input type=\"text\" class=\"formfld unknown\" size=\"2\" id=\"maskbits\" name=\"maskbits\" value=\"";
3661 8c50a9d8 Jean Cyr
		if ($mask['type'] <> "none")
3662 0b4e7542 Jean Cyr
		$form .= $mask['bits'];
3663 8c50a9d8 Jean Cyr
		$form .= "\"";
3664
		if ($mask['type'] == "none")
3665
			$form .= " disabled";
3666
		$form .= " />";
3667 2d46e1e4 Jean Cyr
		$form .= "&nbsp; IPV4 mask bits (1-32)<br/>";
3668 2fbefad6 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=\"";
3669
		if ($mask['type'] <> "none")
3670
		$form .= $mask['bitsv6'];
3671
		$form .= "\"";
3672
		if ($mask['type'] == "none")
3673
			$form .= " disabled";
3674
		$form .= " />";
3675
		$form .= "&nbsp; IPV6 mask bits (1-128)<br/>";
3676 0b4e7542 Jean Cyr
		$form .= "<span class=\"vexpl\">" . gettext("If 'source' or 'destination' slots is chosen, \n"
3677
		      .  "leaving the mask bits blank will create one pipe per host. Otherwise specify \n"
3678
		      .  "the number of 'one' bits in the subnet mask used to group multiple hosts \n"
3679
		      .  "per queue.") . "</span>";
3680 c25a6b6a Ermal Luçi
		$form .= "</td></tr>";
3681 d8484854 Colin Fleming
		$form .= "<tr><td valign=\"middle\" class=\"vncellreq\">" . gettext("Description") . "</td>";
3682 c25a6b6a Ermal Luçi
		$form .= "<td class=\"vncellreq\">";
3683 d8484854 Colin Fleming
		$form .= "<input type=\"text\" id=\"description\" class=\"formfld unknown\" size=\"40\" name=\"description\" value=\"";
3684 c25a6b6a Ermal Luçi
		$form .= $this->GetDescription();
3685 6f1bcc36 Colin Fleming
		$form .= "\" />";
3686 0fa05f45 Colin Fleming
		$form .= "<br/> <span class=\"vexpl\">";
3687 dbaf21d4 Renato Botelho
		$form .= gettext("You may enter a description here for your reference (not parsed).") . "</span>";
3688 c25a6b6a Ermal Luçi
		$form .= "</td></tr>";
3689 d8484854 Colin Fleming
		$form .= "<tr id=\"sprtable4\">";
3690 19190e1a Ermal Luçi
		$form .= "<td></td>";
3691
                $form .= "<td><div id=\"showadvancedboxspr\">";
3692 6f1bcc36 Colin Fleming
                $form .= "<p><input type=\"button\" onclick=\"show_source_port_range()\"";
3693
		$form .= " value=\"" . gettext("Show advanced options") . "\" />";
3694 dda2f35e Colin Fleming
                $form .= "</p></div></td></tr>";
3695 d8484854 Colin Fleming
		$form .= "<tr style=\"display:none\" id=\"sprtable\">";
3696 7da5315d Colin Fleming
		$form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Weight") . "</td>";
3697
		$form .= "<td valign=\"middle\" class=\"vncellreq\">";
3698 19190e1a Ermal Luçi
		$form .= "<input name=\"weight\" type=\"text\" id=\"weight\" size=\"5\" value=\"";
3699 6f1bcc36 Colin Fleming
		$form .= $this->GetWeight() . "\" />";
3700 0fa05f45 Colin Fleming
		$form .= "&nbsp;<br/> <span class=\"vexpl\">" . gettext("Hint: For queues under the same parent "
3701 dbaf21d4 Renato Botelho
		      .  "this specifies the share that a queue gets(values range from 1 to 100, you can leave it blank otherwise)") . "</span>";
3702 19190e1a Ermal Luçi
		$form .= "</td></tr>";
3703 d8484854 Colin Fleming
		$form .= "<tr style=\"display:none\" id=\"sprtable1\">";
3704 7da5315d Colin Fleming
		$form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Packet loss rate") . "</td>";
3705
		$form .= "<td valign=\"middle\" class=\"vncellreq\">";
3706 19190e1a Ermal Luçi
		$form .= "<input name=\"plr\" type=\"text\" id=\"plr\" size=\"5\" value=\"";
3707 6f1bcc36 Colin Fleming
		$form .= $this->GetPlr() . "\" />";
3708 0fa05f45 Colin Fleming
		$form .= "&nbsp;<br/> <span class=\"vexpl\">" . gettext("Hint: in most cases, you "
3709 dbaf21d4 Renato Botelho
			  .  "should specify 0 here (or leave the field empty). "
3710
			  .  "A value of 0.001 means one packet in 1000 gets dropped") . "</span>";
3711 19190e1a Ermal Luçi
		$form .= "</td></tr>";
3712 d8484854 Colin Fleming
		$form .= "<tr style=\"display:none\" id=\"sprtable2\">";
3713 7da5315d Colin Fleming
		$form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Queue Size") . "</td>";
3714 19190e1a Ermal Luçi
		$form .= "<td class=\"vncellreq\">";
3715
		$form .= "<input type=\"text\" id=\"qlimit\" name=\"qlimit\" value=\"";
3716 6f1bcc36 Colin Fleming
		$form .= $this->GetQlimit() . "\" />";
3717 0fa05f45 Colin Fleming
		$form .= "&nbsp;slots<br/>";
3718 dbaf21d4 Renato Botelho
		$form .= "<span class=\"vexpl\">" . gettext("Hint: in most cases, you "
3719
			  .  "should leave the field empty. All packets in this pipe are placed into a fixed-size queue first, "
3720
			  .  "then they are delayed by value specified in the Delay field, and then they "
3721
			  .  "are delivered to their destination.") . "</span>";
3722 19190e1a Ermal Luçi
		$form .= "</td></tr>";
3723 d8484854 Colin Fleming
		$form .= "<tr style=\"display:none\" id=\"sprtable5\">";
3724 7da5315d Colin Fleming
                $form .= "<td valign=\"middle\" class=\"vncellreq\">" . gettext("Bucket Size") . "</td>";
3725 1c3fd96b Ermal Luçi
                $form .= "<td class=\"vncellreq\">";
3726
                $form .= "<input type=\"text\" id=\"buckets\" name=\"buckets\" value=\"";
3727 6f1bcc36 Colin Fleming
                $form .= $this->GetBuckets() . "\" />";
3728 0fa05f45 Colin Fleming
                $form .= "&nbsp;" . gettext("slots") . "<br/>";
3729 dbaf21d4 Renato Botelho
                $form .= "<span class=\"vexpl\">" . gettext("Hint: in most cases, you "
3730
                      .  "should leave the field empty. It increases the hash size set.");
3731 d8484854 Colin Fleming
                $form .= "</span></td></tr>";
3732 1c3fd96b Ermal Luçi
3733 c25a6b6a Ermal Luçi
		$form .= "<input type=\"hidden\" id=\"pipe\" name=\"pipe\"";
3734 6f1bcc36 Colin Fleming
		$form .= " value=\"" . $this->GetPipe() . "\" />";
3735 c25a6b6a Ermal Luçi
3736
		return $form;
3737 ce0117f7 Colin Fleming
3738 d62ba478 Ermal Luçi
	}
3739 c25a6b6a Ermal Luçi
3740 d62ba478 Ermal Luçi
        function update_dn_data(&$data) { 
3741
		$this->ReadConfig($data);
3742
	}
3743 c25a6b6a Ermal Luçi
3744 d62ba478 Ermal Luçi
	function wconfig() {
3745
		$cflink =& get_dn_reference_to_me_in_config($this->GetLink());
3746
            	if (!is_array($cflink))
3747
            		$cflink = array();
3748
		$cflink['name'] = $this->GetQname();
3749
		$cflink['number'] = $this->GetNumber();
3750
            	$cflink['qlimit'] = $this->GetQlimit();
3751
            	$cflink['description'] = $this->GetDescription();
3752
		$cflink['weight'] = $this->GetWeight();
3753
		$cflink['enabled'] = $this->GetEnabled();
3754
		$cflink['buckets'] = $this->GetBuckets();
3755 0b4e7542 Jean Cyr
		$mask = $this->GetMask();
3756
		$cflink['mask'] = $mask['type'];
3757
		$cflink['maskbits'] = $mask['bits'];
3758 2fbefad6 Jean Cyr
                $cflink['maskbitsv6'] = $mask['bitsv6'];
3759 d62ba478 Ermal Luçi
	}
3760 c25a6b6a Ermal Luçi
}
3761
3762 f63d5b66 Helder Pereira
// List of layer7 objects
3763
$layer7_rules_list = array();
3764
3765
class layer7 {
3766
    
3767
    var $rname; //alias
3768
    var $rdescription; //alias description
3769
    var $rport; //divert port
3770
    var $renabled; //rule enabled
3771
    var $rsets = array(); //array of l7 associations
3772
    
3773
    // Auxiliary functions
3774
    
3775
    function GetRName() {
3776
        return $this->rname;
3777
    }
3778
    function SetRName($rname) {
3779
        $this->rname = $rname;
3780
    }
3781
    function GetRDescription() {
3782
        return $this->rdescription;
3783
    }
3784
    function SetRDescription($rdescription) {
3785
        $this->rdescription = $rdescription;
3786
    }
3787
    function GetRPort() {
3788
        return $this->rport;
3789
    }
3790
    function SetRPort($rport) {
3791
        $this->rport = $rport;
3792
    }
3793
    function GetREnabled() {
3794
        return $this->renabled;
3795
    }
3796
    function SetREnabled($value) {
3797
        $this->renabled = $value;
3798
    }
3799
    function GetRl7() {
3800
        return $this->rsets;
3801
    }
3802
    function SetRl7($rsets) {
3803
        $this->rsets = $rsets;
3804
    }
3805
    
3806
    //Add a tuple (rule,sctructure,element) to the $rsets
3807
    
3808
    function add_rule($l7set) {
3809 51b14faa Ermal Lu?i
       	$this->rsets[] = $l7set;
3810 f63d5b66 Helder Pereira
    }
3811
    
3812
    // Build the layer7 rules
3813
    function build_l7_rules() {
3814
        if($this->GetREnabled() == "") {
3815
            return;
3816
        }
3817
        //$l7rules = "#" . $this->rdescription . "\n";
3818
        foreach ($this->rsets as $rl7) {
3819
            $l7rules .= $rl7->build_rules();
3820
        }
3821
        return $l7rules;
3822
    }
3823
    
3824
    // Read the config from array
3825
    function ReadConfig(&$qname, &$q) {
3826
        $this->SetRName($qname);
3827
        $this->SetREnabled($q['enabled']);
3828
        $this->SetRPort($q['divert_port']);
3829
        if(isset($q['description']) && $q['description'] <> "")
3830
            $this->SetRDescription($q['description']);
3831
        $rsets = $q['l7rules'];
3832
        //Put individual rules in the array
3833
	if(is_array($rsets)) {
3834 51b14faa Ermal Lu?i
	    $this->rsets = array(); // XXX: ugly hack
3835 f63d5b66 Helder Pereira
	    foreach($rsets as $l7r) {
3836
	        $l7obj = new l7rule();
3837
	        $l7obj->SetRProtocol($l7r['protocol']);
3838
	        $l7obj->SetRStructure($l7r['structure']);
3839
	        $l7obj->SetRBehaviour($l7r['behaviour']);
3840
	        $this->add_rule($l7obj);
3841
	    }
3842
	}
3843
    }
3844
    
3845
    //Generate a random port for the divert socket
3846
    function gen_divert_port() {
3847
        $dports = get_divert_ports(); //array of used ports
3848 6ec23212 Ermal Lu?i
	$divert_port = 1; // Initialize
3849
	while (($divert_port % 2) != 0 || in_array($divert_port, $dports)) {
3850
		$divert_port = rand(40000, 60000);
3851
	}
3852 f63d5b66 Helder Pereira
        return $divert_port;
3853
    }
3854
    
3855
    //Helps building the left tree
3856
    function build_tree() {
3857 7da5315d Colin Fleming
        $tree = " <li><a href=\"firewall_shaper_layer7.php?container=" . $this->GetRName() ."&amp;action=show\">"; 
3858 f63d5b66 Helder Pereira
        $tree .= $this->GetRName() . "</a>";
3859
	$tree .= "</li>";
3860 ce0117f7 Colin Fleming
3861 f63d5b66 Helder Pereira
	return $tree;
3862
    }
3863
    
3864
    function build_form() {
3865 7da5315d Colin Fleming
        $form = "<tr><td valign=\"middle\" class=\"vncellreq\"><br/>";
3866 dbaf21d4 Renato Botelho
	$form .= gettext("Enable/Disable");
3867 f63d5b66 Helder Pereira
	$form .= "</td><td class=\"vncellreq\">";
3868 96cbc5aa Ermal
	$form .= " <input type=\"checkbox\" id=\"enabled\" name=\"enabled\" value=\"on\" ";
3869
	if ($this->GetREnabled() == "on") {
3870 ce0117f7 Colin Fleming
       	    $form .=  "checked=\"checked\"";
3871 f63d5b66 Helder Pereira
	}
3872 6f1bcc36 Colin Fleming
	$form .= " /><span class=\"vexpl\"> " . gettext("Enable/Disable layer7 Container") . "</span>";
3873 f63d5b66 Helder Pereira
	$form .= "</td></tr>";
3874 7da5315d Colin Fleming
        $form .= "<tr><td valign=\"middle\" class=\"vncellreq\"><br/><span class=\"vexpl\">" . gettext("Name") . "</span></td>";
3875 f63d5b66 Helder Pereira
	$form .= "<td class=\"vncellreq\">";
3876
	$form .= "<input type=\"text\" id=\"container\" name=\"container\" value=\"";
3877 6f1bcc36 Colin Fleming
	$form .= $this->GetRName()."\" />";
3878 f63d5b66 Helder Pereira
	$form .= "</td></tr>";
3879 7da5315d Colin Fleming
	$form .= "<tr><td valign=\"middle\" class=\"vncellreq\">" . gettext("Description") . "</td>";
3880 f63d5b66 Helder Pereira
	$form .= "<td class=\"vncellreq\">";
3881 d8484854 Colin Fleming
	$form .= "<input type=\"text\" class=\"formfld unknown\" size=\"40\" id=\"description\" name=\"description\" value=\"";
3882 f63d5b66 Helder Pereira
	$form .= $this->GetRDescription();
3883 6f1bcc36 Colin Fleming
	$form .= "\" />";
3884 0fa05f45 Colin Fleming
	$form .= "<br/> <span class=\"vexpl\">";
3885 dbaf21d4 Renato Botelho
	$form .= gettext("You may enter a description here for your reference (not parsed).") . "</span>";
3886 f63d5b66 Helder Pereira
	$form .= "</td></tr>";
3887 ce0117f7 Colin Fleming
3888 f63d5b66 Helder Pereira
	return $form;
3889
    }
3890
    
3891
    //Write the setting to the $config array
3892
    function wconfig() {
3893
	global $config;
3894 ce0117f7 Colin Fleming
3895 f63d5b66 Helder Pereira
	if(!is_array($config['l7shaper']['container'])) {
3896
		$config['l7shaper']['container'] = array();
3897
	}
3898
        //
3899
        $cflink =& get_l7c_reference_to_me_in_config($this->GetRName());
3900
	// Test if this rule does exists already
3901
	if(!$cflink) {
3902
		$cflink =& $config['l7shaper']['container'][];
3903
	}
3904
	$cflink['name'] = $this->GetRName();
3905
        $cflink['enabled'] = $this->GetREnabled();
3906
        $cflink['description'] = $this->GetRDescription();
3907
        $cflink['divert_port'] = $this->GetRPort();
3908
        
3909
	//Destroy previously existent rules
3910
	if(is_array($cflink['rules'])) {
3911
		unset($cflink['l7rules']);
3912
	}
3913 ce0117f7 Colin Fleming
3914 f63d5b66 Helder Pereira
        $cflink['l7rules'] = array();
3915 ce0117f7 Colin Fleming
3916 f63d5b66 Helder Pereira
        $i = 0;
3917
        foreach($this->rsets as $rulel7) {
3918
            $cflink['l7rules'][$i]['protocol'] = $rulel7->GetRProtocol();
3919
            $cflink['l7rules'][$i]['structure'] = $rulel7->GetRStructure();
3920
            $cflink['l7rules'][$i]['behaviour'] = $rulel7->GetRBehaviour();
3921
            $i++;
3922
        }
3923
    }
3924
    
3925
    //This function is necessary to help producing the overload options for keep state
3926
    function get_unique_structures() {
3927
        
3928
        $unique_structures = array("action" => false, "dummynet" => false, "altq" => false);
3929
        foreach($this->rsets as $l7rule) {
3930
		if($l7rule->GetRStructure() == "action")
3931
			$unique_structures['action'] = true;
3932
		else if($l7rule->GetRStructure() == "limiter")
3933
			$unique_structures['dummynet'] = true;
3934
		else
3935
			$unique_structures['altq'] = true;
3936
        }
3937
	//Delete non used structures so we don't have to check this in filter.inc
3938
	foreach($unique_structures as $key => $value)
3939
		if(!$value)
3940
			unset($unique_structures[$key]);
3941
        return $unique_structures;
3942
    }
3943
    
3944
    function validate_input($data, &$input_errors) {
3945 2c072899 jim-p
	$reqdfields[] = "container";
3946 dbaf21d4 Renato Botelho
	$reqdfieldsn[] = gettext("Name");
3947 ce0117f7 Colin Fleming
3948 f63d5b66 Helder Pereira
	shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
3949
        
3950
        if (!preg_match("/^[a-zA-Z0-9_-]+$/", $data['container']))
3951 dbaf21d4 Renato Botelho
            $input_errors[] = gettext("Queue names must be alphanumeric and _ or - only.");
3952 f63d5b66 Helder Pereira
    }
3953
    
3954
    function delete_l7c() {
3955 bb37dc86 Ermal
	mwexec("/bin/pkill -f 'ipfw-classifyd .* -p ". $this->GetRPort() . "'", true);
3956 f63d5b66 Helder Pereira
	unset_l7_object_by_reference($this->GetRName());
3957
	cleanup_l7_from_rules($this->GetRName());
3958
    }
3959
}
3960
3961
class l7rule {
3962
    
3963
    var $rprotocol; //protocol
3964
    var $rstructure; //action, limiter, queue
3965
    var $rbehaviour; //allow, block, queue_name, pipe_number ...
3966
    
3967
    //Auxiliary Functions
3968
    
3969
    function GetRProtocol() {
3970
        return $this->rprotocol;
3971
    }
3972
    function SetRProtocol($rprotocol) {
3973
        $this->rprotocol = $rprotocol;
3974
    }
3975
    function GetRStructure() {
3976
        return $this->rstructure;
3977
    }
3978
    function SetRStructure($rstructure) {
3979
        $this->rstructure = $rstructure;
3980
    }
3981
    function GetRBehaviour() {
3982
        return $this->rbehaviour;
3983
    }
3984
    function SetRBehaviour($rbehaviour) {
3985
        $this->rbehaviour = $rbehaviour;
3986
    }
3987
    
3988
    //XXX Do we need to test any particularity for AltQ queues?
3989
    function build_rules() {
3990
	global $dummynet_pipe_list;
3991
	switch ($this->GetRStructure()) {
3992
		case "limiter":
3993
			read_dummynet_config();
3994
			$dn_list =& get_unique_dnqueue_list();
3995
			$found = false;
3996
			if(is_array($dn_list)) {
3997
				foreach($dn_list as $key => $value) {
3998
					if($key == $this->GetRBehaviour()) {
3999
						if($value[0] == "?")
4000
							$l7rule = $this->GetRProtocol() . " = dnqueue " . substr($value, 1) . "\n";
4001
						else
4002
							$l7rule = $this->GetRProtocol() . " = dnpipe " . $value . "\n";
4003
						$found = true;
4004
					}
4005
					if($found)
4006
						break;
4007
				}
4008
			}
4009
			break;
4010
		default: //This is for action and for altq
4011
			$l7rule = $this->GetRProtocol() . " = " . $this->GetRStructure() . " " . $this->GetRBehaviour() . "\n";
4012
			break;
4013
	}
4014
        return $l7rule;
4015
    }
4016
}
4017
4018
/*
4019
 * This function allows to return an array with all the used divert socket ports
4020
 */
4021
function get_divert_ports() {
4022
    global $layer7_rules_list;
4023
    $dports = array();
4024
    
4025
    foreach($layer7_rules_list as $l7r)
4026
        $dports[] = $l7r->GetRPort();
4027
    
4028
    return $dports;
4029
}
4030
4031
function &get_l7c_reference_to_me_in_config(&$name) {
4032
	global $config;
4033 ce0117f7 Colin Fleming
4034 f63d5b66 Helder Pereira
	$ptr = NULL;
4035 ce0117f7 Colin Fleming
4036 f63d5b66 Helder Pereira
	if(is_array($config['l7shaper']['container'])) {
4037
		foreach($config['l7shaper']['container'] as $key => $value) {
4038
			if($value['name'] == $name)
4039
				$ptr =& $config['l7shaper']['container'][$key];
4040
		}
4041
	}	
4042
	return $ptr;
4043
// $ptr can be null. has to be checked later
4044
}
4045
4046
function unset_l7_object_by_reference(&$name) {
4047
	global $config;
4048
        
4049
	if(is_array($config['l7shaper']['container'])) {
4050
		foreach($config['l7shaper']['container'] as $key => $value) {
4051
			if($value['name'] == $name) {
4052
				unset($config['l7shaper']['container'][$key]['l7rules']);
4053
				unset($config['l7shaper']['container'][$key]);
4054
				break;
4055
			}
4056
		}
4057
	}
4058
}
4059
4060
function read_layer7_config() {
4061
    global $layer7_rules_list, $config;
4062
    
4063
    $l7cs = &$config['l7shaper']['container'];
4064
    
4065
    $layer7_rules_list = array();
4066
    
4067
    if (!is_array($config['l7shaper']['container']) || !count($config['l7shaper']['container']))
4068
	return;
4069
    
4070
    foreach ($l7cs as $conf) {
4071
	if (empty($conf['name']))
4072
		continue; /* XXX: grrrrrr at php */ 
4073 62150088 Ermal Lu?i
        $root =& new layer7();
4074 f63d5b66 Helder Pereira
        $root->ReadConfig($conf['name'],$conf);
4075
        $layer7_rules_list[$root->GetRName()] = &$root;
4076
    }
4077
}
4078
4079
function generate_layer7_files() {
4080 6955830f Ermal Lu?i
    global $layer7_rules_list, $g;
4081 f63d5b66 Helder Pereira
    
4082
    read_layer7_config();
4083
    
4084
    if (!empty($layer7_rules_list)) {
4085 1ab56363 Ermal Lu?i
	if (!is_module_loaded("ipdivert.ko"))
4086
		mwexec("/sbin/kldload ipdivert.ko");
4087 effe3da7 Ermal Lu?i
4088 6955830f Ermal Lu?i
	mwexec("rm -f {$g['tmp_path']}/*.l7");
4089 f63d5b66 Helder Pereira
    }
4090
    
4091
    foreach($layer7_rules_list as $l7rules) {
4092
        if($l7rules->GetREnabled()) {
4093
            $filename = $l7rules->GetRName() . ".l7";
4094 6955830f Ermal Lu?i
            $path = "{$g['tmp_path']}/" . $filename;
4095 f63d5b66 Helder Pereira
        
4096
            $rules = $l7rules->build_l7_rules();
4097
        
4098
            $fp = fopen($path,'w');
4099
            fwrite($fp,$rules);
4100
            fclose($fp);
4101 f476ef15 Ermal Lu?i
        }
4102
    }
4103
}
4104
4105
function layer7_start_l7daemon() {
4106 6955830f Ermal Lu?i
    global $layer7_rules_list, $g;
4107 f476ef15 Ermal Lu?i
4108
    /*
4109 1ab56363 Ermal Lu?i
     * XXX: ermal - Needed ?!
4110 f476ef15 Ermal Lu?i
     * read_layer7_config();
4111
     */
4112
4113
    foreach($layer7_rules_list as $l7rules) {
4114
        if($l7rules->GetREnabled()) {
4115
            $filename = $l7rules->GetRName() . ".l7";
4116 6955830f Ermal Lu?i
            $path = "{$g['tmp_path']}/" . $filename;
4117 f476ef15 Ermal Lu?i
4118 1ab56363 Ermal Lu?i
	    unset($l7pid);
4119 be40ce0b Chris Buechler
	    /* Only reread the configuration rather than restart to avoid losing information. */
4120 6f76920c thompsa
	    exec("/bin/pgrep -f 'ipfw-classifyd .* -p ". $l7rules->GetRPort() . "'", $l7pid);
4121 ddd127eb Ermal Lu?i
	    if (count($l7pid) > 0) {
4122 18efed8b Carlos Eduardo Ramos
		log_error(sprintf(gettext("Sending HUP signal to %s"), $l7pid[0]));
4123 ddd127eb Ermal Lu?i
		mwexec("/bin/kill -HUP {$l7pid[0]}");
4124
	    } else {
4125 1ab56363 Ermal Lu?i
		// XXX: Hardcoded number of packets to garbage collect and queue length..
4126 0b1321e2 Ermal
		$ipfw_classifyd_init = "/usr/local/sbin/ipfw-classifyd -n 8 -q 700 -c {$path} -p " . $l7rules->GetRPort() . " -P /usr/local/share/protocols";
4127 1ab56363 Ermal Lu?i
		mwexec_bg($ipfw_classifyd_init);
4128
	    }
4129 f63d5b66 Helder Pereira
        }
4130
    }
4131
}
4132
4133
// This function uses /usr/local/share/protocols as a default directory for searching .pat files
4134
function generate_protocols_array() {
4135
	$protocols = return_dir_as_array("/usr/local/share/protocols");
4136 c7ed2141 sullrich
	$protocols_new = array();
4137 f63d5b66 Helder Pereira
	if(is_array($protocols)) {
4138 850cff07 Ermal Lu?i
		foreach($protocols as $key => $proto) {
4139 20138aba sullrich
			if (strstr($proto, ".pat"))
4140 c7ed2141 sullrich
				$protocols_new[$key] =& str_replace(".pat", "", $proto);
4141 850cff07 Ermal Lu?i
		}
4142 c7ed2141 sullrich
		sort($protocols_new);
4143 f63d5b66 Helder Pereira
	}		
4144 c7ed2141 sullrich
	return $protocols_new;
4145 f63d5b66 Helder Pereira
}
4146
4147
function get_l7_unique_list() {
4148
	global $layer7_rules_list;
4149 ce0117f7 Colin Fleming
4150 f63d5b66 Helder Pereira
	$l7list = array();
4151
	if(is_array($layer7_rules_list)) 
4152
		foreach($layer7_rules_list as $l7c)
4153
			if($l7c->GetREnabled())
4154
				$l7list[] = $l7c->GetRName();
4155 ce0117f7 Colin Fleming
4156 f63d5b66 Helder Pereira
	return $l7list;
4157
}
4158
4159
// Disable a removed l7 container from the filter
4160
function cleanup_l7_from_rules(&$name) {
4161
	global $config;
4162
4163 daee46a5 Helder Pereira
	if(is_array($config['filter']['rule']))
4164
		foreach ($config['filter']['rule'] as $key => $rule) {
4165
			if ($rule['l7container'] == $name)
4166
				unset($config['filter']['rule'][$key]['l7container']);
4167
		}
4168
}
4169
4170
function get_dummynet_name_list() {
4171 ce0117f7 Colin Fleming
4172 daee46a5 Helder Pereira
	$dn_name_list =& get_unique_dnqueue_list();
4173
	$dn_name = array();
4174
	if(is_array($dn_name_list))
4175
		foreach($dn_name_list as $key => $value)
4176
			$dn_name[] = $key;
4177 ce0117f7 Colin Fleming
4178 daee46a5 Helder Pereira
	return $dn_name;
4179 ce0117f7 Colin Fleming
4180 daee46a5 Helder Pereira
}
4181
4182
function get_altq_name_list() {
4183
	$altq_name_list =& get_unique_queue_list();
4184
	$altq_name = array();
4185
	if(is_array($altq_name_list))
4186
		foreach($altq_name_list as $key => $aqobj)
4187
			$altq_name[] = $key;
4188 ce0117f7 Colin Fleming
4189 daee46a5 Helder Pereira
	return $altq_name;
4190 f63d5b66 Helder Pereira
}
4191 c25a6b6a Ermal Luçi
4192 197bfe96 Ermal Luçi
/*
4193
 * XXX: TODO Make a class shaper to hide all these function
4194
 * from the global namespace.
4195
 */
4196
4197
/* 
4198
 * This is a layer violation but for now there is no way 
4199
 * i can find to properly do this with PHP.
4200
 */
4201
function altq_get_default_queue($interface) {
4202
	global $altq_list_queues;
4203 061f78b1 Bill Marquette
4204 197bfe96 Ermal Luçi
	$altq_tmp = $altq_list_queues[$interface];
4205 acebc1ec Ermal
	if ($altq_tmp)
4206 197bfe96 Ermal Luçi
		return $altq_tmp->GetDefaultQueuePresent(); 
4207 acebc1ec Ermal
	else
4208
		return false;
4209 197bfe96 Ermal Luçi
}
4210 061f78b1 Bill Marquette
4211 21a0464c Ermal Luçi
function altq_check_default_queues() {
4212
	global $altq_list_queues;
4213
4214
	$count = 0;
4215
	if (is_array($altq_list_queues)) {
4216
		foreach($altq_list_queues as $altq) {
4217
			if ($altq->GetDefaultQueuePresent())
4218
				$count++;
4219
		}
4220
	}
4221
	else  $count++;;
4222 ce0117f7 Colin Fleming
4223 21a0464c Ermal Luçi
	return 0;
4224
}
4225
4226
function &get_unique_queue_list() {
4227
	global $altq_list_queues;
4228 ce0117f7 Colin Fleming
4229 21a0464c Ermal Luçi
	$qlist = array();
4230
	if (is_array($altq_list_queues)) {
4231
		foreach ($altq_list_queues as $altq) {
4232 12dfe8ca Ermal
			if ($altq->GetEnabled() == "")
4233 146f0fad Ermal
				continue;
4234 21a0464c Ermal Luçi
			$tmplist =& $altq->get_queue_list();
4235 146f0fad Ermal
			foreach ($tmplist as $qname => $link) {
4236
				if ($link->GetEnabled() <> "")
4237
					$qlist[$qname] = $link;	
4238
			}
4239 21a0464c Ermal Luçi
		}
4240
	}
4241
	return $qlist;
4242
}
4243
4244 309ffde9 Ermal Luçi
function &get_unique_dnqueue_list() {
4245 c25a6b6a Ermal Luçi
	global $dummynet_pipe_list;
4246 ce0117f7 Colin Fleming
4247 c25a6b6a Ermal Luçi
	$qlist = array();
4248
	if (is_array($dummynet_pipe_list)) {
4249
		foreach ($dummynet_pipe_list as $dn) {
4250 146f0fad Ermal
			if ($dn->GetEnabled() == "")
4251
				continue;
4252 c25a6b6a Ermal Luçi
			$tmplist =& $dn->get_queue_list();
4253 146f0fad Ermal
			foreach ($tmplist as $qname => $link) {
4254 c25a6b6a Ermal Luçi
				$qlist[$qname] = $link;	
4255 146f0fad Ermal
			}
4256 c25a6b6a Ermal Luçi
		}
4257
	}
4258
	return $qlist;
4259
}
4260
4261 197bfe96 Ermal Luçi
function ref_on_altq_queue_list($parent, $qname) {
4262
	if (isset($GLOBALS['queue_list'][$qname]))
4263
		$GLOBALS['queue_list'][$qname]++;
4264
	else
4265
		$GLOBALS['queue_list'][$qname] = 1;
4266 061f78b1 Bill Marquette
4267 197bfe96 Ermal Luçi
	unref_on_altq_queue_list($parent);
4268
}
4269 061f78b1 Bill Marquette
4270 197bfe96 Ermal Luçi
function unref_on_altq_queue_list($qname) {
4271
	$GLOBALS['queue_list'][$qname]--;
4272
	if ($GLOBALS['queue_list'][$qname] <= 1)
4273
		unset($GLOBALS['queue_list'][$qname]);	
4274
}
4275 061f78b1 Bill Marquette
4276 197bfe96 Ermal Luçi
function read_altq_config() {
4277
	global $altq_list_queues, $config;
4278
	$path = array();
4279 ce0117f7 Colin Fleming
4280 7849bdd5 Ermal Lu?i
	if (!is_array($config['shaper']))
4281
		$config['shaper'] = array();
4282
	if (!is_array($config['shaper']['queue']))
4283
		$config['shaper']['queue'] = array();
4284 197bfe96 Ermal Luçi
	$a_int = &$config['shaper']['queue'];
4285
4286
	$altq_list_queues = array();
4287 ce0117f7 Colin Fleming
4288 197bfe96 Ermal Luçi
	if (!is_array($config['shaper']['queue']))
4289
		return;
4290
4291
	foreach ($a_int as $key => $conf) {
4292 520ad1a4 Ermal
		$int = $conf['interface'];
4293
		$root =& new altq_root_queue();
4294
		$root->SetInterface($int);
4295
		$altq_list_queues[$root->GetInterface()] = &$root;
4296
		$root->ReadConfig($conf);
4297 197bfe96 Ermal Luçi
		array_push($path, $key);
4298
		$root->SetLink($path);
4299
		if (is_array($conf['queue'])) {
4300
			foreach ($conf['queue'] as $key1 => $q) {
4301
				array_push($path, $key1);
4302 92125c97 Ermal Luçi
				/* 
4303 be40ce0b Chris Buechler
				 * XXX: we completely ignore errors here but anyway we must have 
4304 92125c97 Ermal Luçi
				 *	checked them before so no harm should be come from this.
4305
				 */
4306
				$root->add_queue($root->GetInterface(), $q, &$path, $input_errors);
4307 197bfe96 Ermal Luçi
				array_pop($path);
4308
			} 	
4309 520ad1a4 Ermal
		}
4310 197bfe96 Ermal Luçi
		array_pop($path);
4311
	}
4312
}
4313 0a33f73e Scott Ullrich
4314 c25a6b6a Ermal Luçi
function read_dummynet_config() {
4315
	global $dummynet_pipe_list, $config;
4316
	$path = array();
4317 d62ba478 Ermal Luçi
4318 aa10aadc Ermal Lu?i
	if (!is_array($config['dnshaper']))
4319
		$config['dnshaper'] = array();
4320
	if (!is_array($config['dnshaper']['queue']))
4321
		$config['dnshaper']['queue'] = array();
4322 c25a6b6a Ermal Luçi
	$a_int = &$config['dnshaper']['queue'];
4323 2f038c0b Scott Ullrich
4324 c25a6b6a Ermal Luçi
	$dummynet_pipe_list = array();
4325 ce0117f7 Colin Fleming
4326 ec656e20 Ermal Luçi
	if (!is_array($config['dnshaper']['queue'])
4327
		|| !count($config['dnshaper']['queue']))
4328 c25a6b6a Ermal Luçi
		return;
4329
4330
	foreach ($a_int as $key => $conf) {
4331 ec656e20 Ermal Luçi
		if (empty($conf['name']))
4332
			continue; /* XXX: grrrrrr at php */ 
4333 62150088 Ermal Lu?i
		$root =& new dnpipe_class();
4334 d62ba478 Ermal Luçi
		$root->ReadConfig($conf);
4335
		$dummynet_pipe_list[$root->GetQname()] = &$root;
4336
		array_push($path, $key);
4337
		$root->SetLink($path);
4338
		if (is_array($conf['queue'])) {
4339
			foreach ($conf['queue'] as $key1 => $q) {
4340
				array_push($path, $key1);
4341
				/* 
4342 be40ce0b Chris Buechler
				 * XXX: we completely ignore errors here but anyway we must have 
4343 d62ba478 Ermal Luçi
				 *	checked them before so no harm should be come from this.
4344
				 */	
4345
				$root->add_queue($root->GetQname(), $q, &$path, $input_errors);
4346 c25a6b6a Ermal Luçi
				array_pop($path);
4347 d62ba478 Ermal Luçi
			} 	
4348
		}
4349
		array_pop($path);
4350 c25a6b6a Ermal Luçi
	}
4351
}
4352 0a33f73e Scott Ullrich
4353 197bfe96 Ermal Luçi
function get_interface_list_to_show() {
4354
	global $altq_list_queues, $config;
4355 057399e4 Ermal Luçi
	global $shaperIFlist;
4356
4357 197bfe96 Ermal Luçi
	$tree = "";
4358 057399e4 Ermal Luçi
	foreach ($shaperIFlist as $shif => $shDescr) {
4359
		if ($altq_list_queues[$shif]) {
4360 197bfe96 Ermal Luçi
			continue;
4361 a843b04f Ermal Luçi
		} else  {
4362 057399e4 Ermal Luçi
			if (!is_altq_capable(get_real_interface($shif)))
4363 0b033d22 Ermal Luçi
				continue;
4364 7da5315d Colin Fleming
			$tree .= " <li><a href=\"firewall_shaper.php?interface=".$shif."&amp;action=add\">".$shDescr."</a></li>";
4365 197bfe96 Ermal Luçi
		}
4366
	}
4367 ce0117f7 Colin Fleming
4368 197bfe96 Ermal Luçi
	return $tree;
4369
}
4370 061f78b1 Bill Marquette
4371 197bfe96 Ermal Luçi
function filter_generate_altq_queues() {
4372
	global $altq_list_queues;
4373 ce0117f7 Colin Fleming
4374 197bfe96 Ermal Luçi
	read_altq_config();
4375 061f78b1 Bill Marquette
4376 197bfe96 Ermal Luçi
	$altq_rules = "";
4377
	foreach ($altq_list_queues as $altq) 
4378
		$altq_rules .= $altq->build_rules();
4379 0f0c6a9e Scott Ullrich
4380 197bfe96 Ermal Luçi
	return $altq_rules;
4381
}
4382 0f0c6a9e Scott Ullrich
4383 85a236e9 Ermal
function dnqueue_find_nextnumber() {
4384
	global $dummynet_pipe_list;
4385
4386
	$dnused = array();
4387
	if (is_array($dummynet_pipe_list)) {
4388
		foreach ($dummynet_pipe_list as $dn) {
4389
			$tmplist =& $dn->get_queue_list();
4390
			foreach ($tmplist as $qname => $link) {
4391
				if ($link[0] == "?")
4392
					$dnused[$qname] = substr($link, 1);
4393
			}
4394
		}
4395
	}
4396
4397
	sort($dnused, SORT_NUMERIC);
4398
	$dnnumber = 0;
4399
	$found = false;
4400
	foreach ($dnused as $dnnum) {
4401
		if (($dnnum - $dnnumber) > 1) {
4402
			$dnnumber = $dnnum + 1;
4403
			$found = true;
4404
			break;
4405
		} else
4406
			$dnnumber = $dnnum;
4407
	}
4408
4409
	if ($found == false)
4410
		$dnnumber++;
4411
4412
	unset($dnused, $dnnum, $found);
4413
	return $dnnumber;
4414
}
4415
4416
function dnpipe_find_nextnumber() {
4417
	global $dummynet_pipe_list;
4418
4419
	$dnused = array();
4420
	foreach ($dummynet_pipe_list as $dn)
4421
		$dnused[] = $dn->GetNumber();
4422
4423
	sort($dnused, SORT_NUMERIC);
4424
	$dnnumber = 0;
4425
	$found = false;
4426
	foreach ($dnused as $dnnum) {
4427
		if (($dnnum - $dnnumber) > 1) {
4428
			$dnnumber = $dnnum + 1;
4429
			$found = true;
4430
			break;
4431
		} else
4432
			$dnnumber = $dnnum;
4433
	}
4434
4435
	if ($found == false)
4436
		$dnnumber++;
4437
4438
	unset($dnused, $dnnum, $found);
4439
	return $dnnumber;
4440
}
4441
4442 d62ba478 Ermal Luçi
function filter_generate_dummynet_rules() {
4443 d41e63b6 Ermal
	global $g, $dummynet_pipe_list;
4444 ce0117f7 Colin Fleming
4445 c25a6b6a Ermal Luçi
	read_dummynet_config();
4446 ce0117f7 Colin Fleming
4447 ec656e20 Ermal Luçi
	if (!empty($dummynet_pipe_list)) {
4448 67179472 Ermal
		if (!is_module_loaded("dummynet.ko")) {
4449 1ab56363 Ermal Lu?i
			mwexec("/sbin/kldload dummynet");
4450 67179472 Ermal
			mwexec("/sbin/sysctl net.inet.ip.dummynet.io_fast=1 net.inet.ip.dummynet.hash_size=256");
4451
		}
4452 d62ba478 Ermal Luçi
	}
4453 c25a6b6a Ermal Luçi
4454
	$dn_rules = "";
4455 7807634c Ermal Luçi
	foreach ($dummynet_pipe_list as $dn) 
4456 c25a6b6a Ermal Luçi
		$dn_rules .= $dn->build_rules();
4457
4458 e3e5160c Ermal
	if (!empty($dn_rules)) {
4459 d41e63b6 Ermal
		file_put_contents("{$g['tmp_path']}/rules.limiter", $dn_rules);
4460
		mwexec("/sbin/ipfw {$g['tmp_path']}/rules.limiter");
4461
	}
4462 c25a6b6a Ermal Luçi
}
4463 0a33f73e Scott Ullrich
4464 197bfe96 Ermal Luçi
function build_iface_without_this_queue($iface, $qname) {
4465
	global $g, $altq_list_queues;
4466 d34ade52 Michele Di Maria
	global $shaperIFlist;
4467 0a33f73e Scott Ullrich
4468 197bfe96 Ermal Luçi
	$altq =& $altq_list_queues[$iface];
4469 d7f4030a Ermal
	if ($altq)
4470
		$scheduler = ": " . $altq->GetScheduler();
4471 197bfe96 Ermal Luçi
	$form = "<tr><td width=\"20%\" >";
4472 7da5315d Colin Fleming
	$form .= "<a href=\"firewall_shaper.php?interface=" . $iface . "&amp;queue=" . $iface."&amp;action=show\">". $shaperIFlist[$iface] . $scheduler."</a>";
4473 dbaf21d4 Renato Botelho
	$form .= "</td></tr>";
4474
	$form .= "<tr><td width=\"100%\" class=\"vncellreq\">";
4475
	$form .= "<a href=\"firewall_shaper_queues.php?interface=";
4476 7da5315d Colin Fleming
	$form .= $iface . "&amp;queue=". $qname . "&amp;action=add\">";
4477 dbaf21d4 Renato Botelho
	$form .= "<img src=\"";
4478
	$form .= "./themes/".$g['theme']."/images/icons/icon_plus.gif\"";
4479 6f1bcc36 Colin Fleming
	$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Clone shaper/queue on this interface\" alt=\"clone\" />";
4480 dbaf21d4 Renato Botelho
	$form .= gettext(" Clone shaper/queue on this interface") . "</a></td></tr>";
4481 92125c97 Ermal Luçi
4482 dbaf21d4 Renato Botelho
	return $form;
4483 0a33f73e Scott Ullrich
4484 197bfe96 Ermal Luçi
}
4485 0a33f73e Scott Ullrich
4486 061f78b1 Bill Marquette
4487 d8484854 Colin Fleming
$default_shaper_msg =  "<tr><td align=\"center\" width=\"80%\">";
4488
$default_shaper_msg .= "<span class=\"vexpl\"><strong><b>" . sprintf(gettext("Welcome to the %s Traffic Shaper."), $g['product_name']) . "</b><br />";
4489 dbaf21d4 Renato Botelho
$default_shaper_msg .= gettext("The tree on the left helps you navigate through the queues <br />"
4490
                    .  "buttons at the bottom represent queue actions and are activated accordingly.");
4491 d8484854 Colin Fleming
$default_shaper_msg .= "</strong></span>";
4492 197bfe96 Ermal Luçi
$default_shaper_msg .= "</td></tr>";
4493 061f78b1 Bill Marquette
4494 d8484854 Colin Fleming
$dn_default_shaper_msg =  "<tr><td align=\"center\" width=\"80%\">";
4495
$dn_default_shaper_msg .= "<span class=\"vexpl\"><strong><b>" . sprintf(gettext("Welcome to the %s Traffic Shaper."), $g['product_name']) . "</b><br />";
4496 dbaf21d4 Renato Botelho
$dn_default_shaper_msg .= gettext("The tree on the left helps you navigate through the queues <br />"
4497
                       .  "buttons at the bottom represent queue actions and are activated accordingly.");
4498 d8484854 Colin Fleming
$dn_default_shaper_msg .= "</strong></span>";
4499 d62ba478 Ermal Luçi
$dn_default_shaper_msg .= "</td></tr>";
4500
4501 6955830f Ermal Lu?i
?>