Project

General

Profile

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