Project

General

Profile

Download (84.4 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
		Copyright (C) 2008 Ermal Lu?i
4
		All rights reserved.
5

    
6
		Redistribution and use in source and binary forms, with or without
7
		modification, are permitted provided that the following conditions are met:
8

    
9
		1. Redistributions of source code must retain the above copyright notice,
10
		   this list of conditions and the following disclaimer.
11

    
12
		2. Redistributions in binary form must reproduce the above copyright
13
		   notice, this list of conditions and the following disclaimer in the
14
		   documentation and/or other materials provided with the distribution.
15

    
16
		THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17
		INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18
		AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19
		AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20
		OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
		SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
		INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
		CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
		ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
		POSSIBILITY OF SUCH DAMAGE.
26
*/
27

    
28
/* include all configuration functions */
29
require_once("functions.inc");
30
require_once("pkg-utils.inc");
31
require_once("notices.inc");
32
//require_once("guiconfig.inc");
33

    
34
/*
35
 * I admit :) this is derived from xmplparse.inc StartElement()
36
 */
37
function &get_reference_to_me_in_config(&$mypath) {
38
	global $config;
39

    
40
		 $ptr =& $config['shaper'];
41
	foreach ($mypath as $indeks) {
42
				$ptr =& $ptr['queue'][$indeks];
43
		}
44

    
45
	return $ptr;
46
}
47
function unset_object_by_reference(&$mypath) {
48
	global $config;
49

    
50
		$ptr =& $config['shaper'];
51
		for ($i = 0; $i < count($mypath) - 1; $i++) {
52
				$ptr =& $ptr['queue'][$mypath[$i]];
53
		}
54
	unset($ptr['queue'][$mypath[$i]]);
55
}
56

    
57
function clean_child_queues($type, $mypath) {
58
	$ref = &get_reference_to_me_in_config($mypath);
59

    
60
	switch ($type) {
61
	case 'HFSC':
62
		if (isset($ref['borrow'])) unset($ref['borrow']);		
63
		if (isset($ref['hogs'])) unset($ref['hogs']);
64
		if (isset($ref['buckets'])) unset($ref['buckets']);
65
		break;
66
	case 'PRIQ':
67
		if (isset($ref['borrow'])) unset($ref['borrow']);		
68
		if (isset($ref['bandwidth'])) unset($ref['bandwidth']);
69
		if (isset($ref['bandwidthtype'])) unset($ref['bandwidthtype']);
70
		/* fall through */
71
	case 'FAIRQ':
72
		if (isset($ref['borrow'])) unset($ref['borrow']);		
73
		/* fall through */
74
	case 'CBQ':
75
		if (isset($ref['realtime'])) unset($ref['realtime']);	
76
		if (isset($ref['realtime1'])) unset($ref['realtime1']);
77
		if (isset($ref['realtime2'])) unset($ref['realtime2']);
78
		if (isset($ref['realtime3'])) unset($ref['realtime3']);
79
		if (isset($ref['upperlimit'])) unset($ref['upperlimit']);
80
		if (isset($ref['upperlimit1'])) unset($ref['upperlimit1']);
81
		if (isset($ref['upperlimit2'])) unset($ref['upperlimit2']);
82
		if (isset($ref['upperlimit3'])) unset($ref['upperlimit3']);
83
		if (isset($ref['linkshare'])) unset($ref['linkshare']);
84
		if (isset($ref['linkshare1'])) unset($ref['linkshare1']);
85
		if (isset($ref['linkshare2'])) unset($ref['linkshare2']);
86
		if (isset($ref['linkshare3'])) unset($ref['linkshare3']);	
87
		if (isset($ref['hogs'])) unset($ref['hogs']);
88
		if (isset($ref['buckets'])) unset($ref['buckets']);
89
		break;
90
	}
91
}
92

    
93
function get_bandwidthtype_scale($type) {
94
        switch ($type) {
95
        case "Gb":
96
                $factor = 1000 * 1000 * 1000;
97
        break;
98
        case "Mb":
99
                $factor = 1000 * 1000;
100
        break;
101
        case "Kb":
102
                $factor = 1000;
103
        break;
104
        case "b":
105
        default:
106
                $factor = 1;
107
        break;
108
        }
109
        return floatval($factor);
110
}
111

    
112
function get_hfsc_bandwidth($object, $bw) {
113
	$pattern= "/[0-9]+/";
114
        if (preg_match($pattern, $bw, $match))
115
                $bw_1 = $match[1];
116
        else
117
                return 0;
118
        $pattern= "/(b|Kb|Mb|Gb|%)/";
119
        if (preg_match($pattern, $bw, $match)) {
120
                switch ($match[1]) {
121
                case '%':
122
                        $bw_1 = $bw_1 / 100 * get_interface_bandwidth($object);
123
                        break;
124
                default:
125
                        $bw_1 = $bw_1 * get_bandwidthtype_scale($match[0]);
126
                        break;
127
                }
128
		return floatval($bw_1);
129
        } else
130
                return 0;
131
}
132

    
133
function get_interface_bandwidth($object) {
134
	global $altq_list_queues;
135

    
136
        $int = $object->GetInterface();
137
        $altq =& $altq_list_queues[$int];
138
        if ($altq) {
139
                $bw_3 = $altq->GetBandwidth();
140
                $bw_3 = $bw_3 *  get_bandwidthtype_scale($altq->GetBwscale());
141
		return floatval($bw_3);
142
        } else return 0;
143
}
144

    
145
/*
146
 * This is duplicated here since we cannot include guiconfig.inc.
147
 * Including it makes all stuff break.
148
 */
149
function shaper_do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors) {
150

    
151
        /* check for bad control characters */
152
        foreach ($postdata as $pn => $pd) {
153
                if (is_string($pd) && preg_match("/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/", $pd)) {
154
                        $input_errors[] = "The field '" . $pn . "' contains invalid characters.";
155
                }
156
        }
157

    
158
        for ($i = 0; $i < count($reqdfields); $i++) {
159
                if ($postdata[$reqdfields[$i]] == "") {
160
                        $input_errors[] = "The field '" . $reqdfieldsn[$i] . "' is required.";
161
                }
162
        }
163
}
164

    
165
function cleanup_queue_from_rules($queue) {
166
	global $config;
167

    
168
	foreach ($config['filter']['rule'] as $rule) {
169
		if ($rule['defaultqueue'] == $queue)
170
			unset($rule['defaultqueue']);
171
		if ($rule['ackqueue'] == $queue)
172
			unset($rule['ackqueue']);
173
	}
174
	foreach ($config['interfaces'] as $if => $ifdata) {
175
			if ($ifdata['ftpqueue'] == $queue) {
176
				unset($config['interfaces'][$if]['ftpqueue']);
177
				break;
178
			}
179
	}
180
}
181

    
182
class altq_root_queue {
183
		var $interface;
184
		var $tbrconfig ;
185
		var $bandwidth;
186
		var $bandwidthtype; /* b, Kb, Mb */
187
		var $scheduler;
188
		var $qlimit;
189
		var $queues = array();
190
		var $qenabled;
191
		var $link;
192
		var $default_present; /* if we have a default queue set */
193
		var $available_bw; /* in b/s */
194

    
195
		/* Accesor functions */
196
	function GetAvailableBandwidth() {
197
		return $this->available_bw;
198
	}
199
	function SetAvailableBandwidth($bw) {
200
		$this->available_bw = $bw;
201
	}
202
	function SetDefaultQueuePresent($value) {
203
		$this->default_present = $value;
204
	}
205
	function GetDefaultQueuePresent() {
206
		return trim($this->default_present);
207
	}
208
	function SetLink($link) {
209
		$this->link = $link;
210
	}
211
	function GetLink() {
212
		return $this->link;
213
	}	
214
	function GetEnabled() {
215
		return $this->qenabled;
216
	}
217
	function SetEnabled($value) {
218
		$this->qenabled = $value;
219
	}
220
	function CanHaveChilds() {
221
		return true;
222
	}
223
	function CanBeDeleted() {
224
		return false;
225
	}
226
	function GetQname() {
227
		return $this->interface;
228
	}
229
	function SetQname($name) {
230
		$this->interface = trim($name);
231
	}
232
	function GetInterface() {
233
			return $this->interface;
234
	}
235
	function SetInterface($name) {
236
			$this->interface = trim($name);
237
	}
238
	function GetTbrConfig() {
239
			return $this->tbrconfig;
240
	}
241
	function SetTbrConfig($tbrconfig) {
242
			$this->tbrconfig = $tbrconfig;
243
	}
244
	function GetBandwidth() {
245
			return $this->bandwidth;
246
	}
247
	function SetBandwidth($bw) {
248
			$this->bandwidth = $bw;
249
	}
250
	function GetBwscale() {
251
			return $this->bandwidthtype;
252
	}
253
	function SetBwscale($bwscale) {
254
			$this->bandwidthtype = $bwscale;
255
	}
256
	function GetScheduler() {
257
			return $this->scheduler;
258
	}
259
	function SetScheduler($scheduler) {
260
			$this->scheduler = trim($scheduler);
261
	}
262
	function GetQlimit() {
263
		return $this->qlimit;
264
	}
265
	function SetQlimit($limit) {
266
		$this->qlimit = $limit;
267
	}
268
	
269
	function validate_input($data, &$input_errors) {
270
		
271
		$reqfields[] = "bandwidth";
272
		$reqdfieldsn[] = "Bandwidth";
273
		$reqfields[] = "bandwidthtype";
274
		$reqdfieldsn[] = "Bandwidthtype";
275
		
276
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
277
		
278
                if ($data['bandwidth'] && (!is_numeric($data['bandwidth'])))
279
                                                $input_errors[] = "Bandwidth must be an integer.";
280
                if ($data['bandwidth'] < 0)
281
                                                $input_errors[] = "Bandwidth cannot be negative.";
282
                if ($data['qlimit'] && (!is_numeric($data['qlimit'])))
283
                                                $input_errors[] = "Qlimit must be an integer.";
284
	 	if ($data['qlimit'] < 0)
285
                                                $input_errors[] = "Qlimit must be an positive.";
286
                if ($data['tbrconfig'] && (!is_numeric($data['tbrconfig'])))
287
                                                $input_errors[] = "Tbrsize must be an integer.";
288
                if ($data['tbrconfig'] < 0)
289
                                                $input_errors[] = "Tbrsize must be an positive.";
290
	}
291

    
292

    
293
	/* Implement this to shorten some code on the frontend page */
294
		function ReadConfig(&$conf) {
295
			if (isset($conf['tbrconfig']))
296
				$this->SetTbrConfig($conf['tbrconfig']);
297
			if ($conf['bandwidth'] <> "") {
298
				$this->SetBandwidth($conf['bandwidth']);
299
				if ($conf['bandwidthtype'] <> "")
300
					$this->SetBwscale($conf['bandwidthtype']);
301
			}
302
		if (isset($conf['scheduler'])) {
303
				if ($this->GetScheduler() != $conf['scheduler']) {
304
					foreach ($this->queues as $q) {
305
						clean_child_queues($conf['scheduler'], $this->GetLink());
306
						$q->clean_queue($conf['scheduler']);
307
					}
308
				}
309
				$this->SetScheduler($conf['scheduler']);
310
			}
311
		if (isset($conf['qlimit']) && $conf['qlimit'] <> "")
312
			$this->SetQlimit($conf['qlimit']);
313
		if (isset($conf['name']))
314
			$this->SetQname($conf['name']);		
315
		//if (isset($conf['enabled']) && $conf['enabled'] == "on")
316
			$this->SetEnabled("on");
317

    
318
	}
319
	
320
	function copy_queue($interface, &$cflink) {
321
                $cflink['interface'] = $interface;
322
                $cflink['name'] = $interface;
323
                $cflink['scheduler'] = $this->GetScheduler();
324
                $cflink['bandwidth'] = $this->GetBandwidth();
325
                $cflink['bandwidthtype'] = $this->GetBwscale();
326
                $cflink['qlimit'] = $this->GetQlimit();
327
                $cflink['tbrconfig'] = $this->GetTbrConfig();
328
                $cflink['enabled'] = $this->GetEnabled();
329
		if (is_array($this->queues)) {
330
			$cflink['queue'] = array();
331
			foreach ($this->queues as $q) {
332
				$cflink['queue'][$q->GetQname()] = array();
333
				$q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
334
			}
335
		}
336
	}
337

    
338

    
339
		function &get_queue_list($q = null) {
340
			$qlist = array();
341

    
342
			$qlist[$this->GetQname()] = & $this;
343
			if (is_array($this->queues)) {
344
				foreach ($this->queues as $queue)
345
					$queue->get_queue_list(&$qlist);
346
			}
347
			return $qlist;
348
		}
349

    
350
		function &add_queue($interface, &$queue, &$path, &$input_errors) {
351

    
352
			if (!is_array($this->queues))
353
				$this->queues = array();
354
				
355
			switch ($this->GetScheduler()) {
356
				case "PRIQ":
357
					$q =& new priq_queue();
358
					break;
359
				case "HFSC":
360
					$q =& new hfsc_queue();
361
					break;
362
				case "CBQ":
363
					$q =& new cbq_queue();
364
					break;
365
				case "FAIRQ":
366
					$q =& new fairq_queue();
367
					break;
368
				default:
369
					/* XXX: but should not happen anyway */ 
370
					return;
371
					break;
372
			}
373
			$q->SetLink($path);
374
			$q->SetInterface($this->GetInterface());
375
			$q->SetEnabled("on");
376
			$q->SetParent(&$this);
377
			$q->ReadConfig($queue);
378
			$q->validate_input($queue, $input_errors);
379
                 if (count($input_errors)) {
380
                       return $q;
381
                 }
382

    
383
                 if (isset($queue['bandwidth'])) {
384
                         switch ($queue['bandwidthtype']) {
385
                         case "%":
386
                                $myBw = $this->GetAvailableBandwidth() * $queue['bandwidth'] / 100;
387
                                break;
388
                        default:
389
                                $myBw = $queue['bandwidth'] * get_bandwidthtype_scale($queue['bandwdithtype']);
390
                                break;
391
                        }
392
                 	}
393
			$q->SetAvailableBandwidth($myBw);
394
                        $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
395
			$this->queues[$q->GetQname()] = &$q; 
396
			ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
397
			if (is_array($queue['queue'])) {
398
				foreach ($queue['queue'] as $key1 => $que) {
399
					array_push($path, $key1);
400
								$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
401
					array_pop($path);
402
						}
403
			}
404
	
405
			return $q;
406
		}
407

    
408
		/* interface here might be optional */
409
		function &find_queue($interface, $qname) {
410
			if ($qname == $this->GetQname()) {
411
				return $this;
412
			} 
413
			foreach ($this->queues as $q) {
414
				$result =& $q->find_queue("", $qname);
415
				if ($result)
416
					return $result;
417
			}
418
		}
419

    
420
	function &find_parentqueue($interface, $qname) {
421
		if ($qname == $interface) {
422
			$result =  NULL;
423
		} else if ($this->queues[$qname])	 {
424
			$result = $this;
425
		} else if ($this->GetScheduler() <> "PRIQ") {
426
			foreach ($this->queues as $q) {
427
				$result = $q->find_parentqueue("", $qname);
428
				if ($result)
429
					return $result;
430
			}
431
		}
432
	}
433

    
434
	function build_tree() {
435
		$tree = " <li><a href=\"firewall_shaper.php?interface=".$this->GetInterface()."&queue=". $this->GetInterface()."&action=show"; 
436
		$tree .= "\">" . $this->GetInterface() . "</a>";
437
		if (is_array($this->queues)) {
438
			$tree .= "<ul>";
439
			foreach ($this->queues as $q)  {
440
				$tree .= $q->build_tree();
441
			}
442
		$tree .= "</ul>";
443
		}
444
		$tree .= "</li>";
445
		return $tree;
446
	}
447
	
448
	function delete_queue() { 
449
		foreach ($this->queues as $q) {
450
		$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
451
			$q->delete_queue();			
452
		}
453
		unset_object_by_reference($this->GetLink());
454
	 }
455

    
456
	function delete_all() {
457
                if (count($this->queues)) {
458
                        foreach ($this->queues as $q) {
459
                        	$q->delete_all();
460
                        	unset_object_by_reference($q->GetLink());
461
                                unset($q);
462
               		}
463
        	        unset($this->queues);
464
                }
465
        }
466

    
467
	/*
468
	 * First it spits:
469
	 * altq on $interface ..............
470
	 *      then it goes like
471
	 *      foreach ($queues as $qkey => $queue)
472
	 *              this->queues[$qkey]->build_rule();
473
	 */
474
	function build_rules() {
475
		if (count($this->queues) > 0 && $this->GetEnabled()) {
476
			$rules = " altq on  " . convert_friendly_interface_to_real_interface_name($this->GetInterface());
477
			if ($this->GetScheduler())
478
					$rules .= " ".strtolower($this->GetScheduler());
479
			if ($this->GetBandwidth())
480
					$rules .= " bandwidth ".trim($this->GetBandwidth());
481
			if ($this->GetBwscale())
482
					$rules .= $this->GetBwscale();
483
			if ($this->GetTbrConfig())
484
					$rules .= " tbrsize ".$this->GetTbrConfig();
485
			if (count($this->queues)) {
486
					$i = count($this->queues);
487
					$rules .= " queue { ";
488
					foreach ($this->queues as $qkey => $qnone) {
489
							if ($i > 1) {
490
									$i--;
491
									$rules .= " {$qkey}, ";
492
							} else
493
									$rules .= " {$qkey} ";
494
					}
495
					$rules .= " } \n";
496
					foreach ($this->queues as $q) {
497
							$rules .= $q->build_rules();
498
					}
499
			}
500
		}
501
		$rules .= " \n";
502
		return $rules;
503
	}
504

    
505
	function build_javascript() {
506
			$javascript = "<script type=\"text/javascript\">";
507
			$javascript .= "function mySuspend() {";
508
			$javascript .= "if (document.layers && document.layers['shaperarea'] != null);";
509
			$javascript .= "document.layers['shaperarea'].visibility = 'hidden';";
510
			$javascript .= "else if (document.all)";
511
			$javascript .= "document.all['shaperarea'].style.visibility = 'hidden';";
512
			$javascript .= "}";
513

    
514
			$javascript .= "function myResume() {";
515
			$javascript .= "if (document.layers && document.layers['shaperarea'] != null)";
516
			$javascript .= "document.layers['shaperarea'].visibility = 'visible';";
517
			$javascript .= "else if (document.all)";
518
			$javascript .= "document.all['shaperarea'].style.visibility = 'visible';";
519
			$javascript .= "}";
520
			$javascript .= "</script>";
521

    
522
			return $javascript;
523
	}
524
	
525
	function build_shortform() {
526
			global $g;
527

    
528
			$altq =& $this;
529
			if ($altq)
530
					$scheduler = ": " . $altq->GetScheduler();
531
			$form = "<tr><td width=\"20%\" class=\"vtable\">";
532
			$form .= "<a href=\"firewall_shaper.php?interface" . $this->GetInterface() . "&queue=". $this->GetInterface()."&action=show\">".$this->GetInterface().": ".$scheduler."</a>";
533
			$form .= "</td></tr>";
534
			$form .= "<tr>";
535
			$form .= "<td width=\"50%\" class=\"vncellreq\">";
536
			$form .= "Bandwidth: " . $this->GetBandwidth().$this->GetBwscale();
537
			$form .= "</td><td width=\"50%\"></td></tr>";
538
			$form .= "<tr><td width=\"20%\" class=\"vncellreq\">";
539
			$form .= "<a href=\"firewall_shaper_queues.php?interface=";
540
			$form .= $this->GetInterface() . "&queue=";
541
			$form .= $this->GetQname() . "&action=delete\">";
542
			$form .= "<img src=\"";
543
			$form .= "./themes/".$g['theme']."/images/icons/icon_x.gif\"";
544
			$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Disable shaper on i
545
nterface\">";
546
			$form .= "<span>Disable shaper on interface</span></a></td></tr>";
547

    
548
			return $form;
549

    
550
	}
551
		/*
552
		 * For requesting the parameters of the root queue
553
		 * to the user like the traffic wizard does.
554
		 */
555
	function build_form() { 
556
		$form = "<tr><td valign=\"top\" class=\"vncellreq\"><br><span class=\"vexpl\">Name</span></td>";
557
		$form .= "<td class=\"vncellreq\">";
558
		$form .= "<strong>".$this->GetQname()."</strong>";
559
		$form .= "</td></tr>";
560
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Scheduler Type ";
561
		$form .= "</td>";
562
		$form .= "<td class=\"vncellreq\">";
563
		$form .= "<select id=\"scheduler\" name=\"scheduler\" class=\"formselect\">";
564
		$form .= "<option value=\"HFSC\"";
565
		if ($this->GetScheduler() == "HFSC")
566
			$form .= " selected=\"yes\"";
567
		$form .= ">HFSC</option>";
568
		$form .= "<option value=\"CBQ\"";
569
		if ($this->GetScheduler() == "CBQ")
570
			$form .= " selected=\"yes\"";
571
		$form .= ">CBQ</option>";
572
		$form .= "<option value=\"FAIRQ\"";
573
                if ($this->GetScheduler() == "FAIRQ")
574
                	$form .= " selected=\"yes\"";
575
                $form .= ">FAIRQ</option>";
576
		$form .= "<option value=\"PRIQ\"";
577
		if ($this->GetScheduler() == "PRIQ")
578
			$form .= " selected=\"yes\"";
579
		$form .= ">PRIQ</option>";
580
		$form .= "</select>";
581
		$form .= "<br> <span class=\"vexpl\">";
582
		$form .= "NOTE: changing this changes all queues underneath!";
583
		$form .= " Beaware you can loose information.";
584
		$form .= "</span>";
585
		$form .= "</td></tr>";
586
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Bandwidth";
587
		$form .= "</td><td class=\"vncellreq\">";
588
		$form .= "<input type=\"text\" id=\"bandwidth\" name=\"bandwidth\" value=\"";
589
		$form .= $this->GetBandwidth() . "\">"; 
590
		$form .= "<select id=\"bandwidthtype\" name=\"bandwidthtype\" class=\"formselect\">";
591
		$form .= "<option value=\"Kb\"";
592
		if ($this->GetBwscale() == "Kb")
593
			$form .= " selected=\"yes\"";
594
		$form .= ">Kbit/s</option>";
595
		$form .= "<option value=\"Mb\"";
596
		if ($this->GetBwscale() == "Mb")
597
			$form .= " selected=\"yes\"";
598
		$form .= ">Mbit/s</option>";
599
		$form .= "<option value=\"Gb\"";
600
		if ($this->GetBwscale() == "Gb")
601
			$form .= " selected=\"yes\"";
602
		$form .= ">Gbit/s</option>";		
603
		$form .= "<option value=\"\"";
604
		if ($this->GetBwscale() == "b")
605
			$form .= " selected=\"yes\"";
606
		$form .= ">Bit/s</option>";
607
		$form .= "</select>";
608
		$form .= "</td></tr>";
609
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Queue Limit</td>";
610
		$form .= "<td class=\"vncellreq\">";
611
		$form .= "<input type=\"text\" id=\"qlimit\" name=\"qlimit\" value=\"";
612
		$form .= $this->GetQlimit();
613
		$form .= "\">";
614
		$form .= "</td></tr>";
615
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Tbr Size</td>";
616
		$form .= "<td class=\"vncellreq\">";
617
		$form .= "<input type=\"text\" id=\"tbrconfig\" name=\"tbrconfig\" value=\"";
618
		$form .= $this->GetTbrConfig();
619
		$form .= "\">";
620
		$form .= "<br> <span class=\"vexpl\">";
621
		$form .= "Adjusts the size, in bytes, of the token bucket regulator.";
622
		$form .= "If not specified, heuristics based on the interface ";
623
		$form .= "bandwidth are used to determine the size.";
624
				$form .= "</span></td></tr>";
625
		$form .= "<input type=\"hidden\" id=\"interface\" name=\"interface\"";
626
		$form .= " value=\"" . $this->GetInterface() . "\">";
627
		$form .= "<input type=\"hidden\" id=\"name\" name=\"name\" value=\"".$this->GetQname()."\" >";
628

    
629

    
630
		return $form;
631
	}
632

    
633
		function update_altq_queue_data(&$data) { 
634
		$this->ReadConfig($data);
635
	}
636
	
637
	/*
638
	 * Should call on each of it queues and subqueues
639
	 * the same function much like build_rules();
640
	 */
641
	function wconfig() { 
642
		$cflink = &get_reference_to_me_in_config($this->GetLink());
643
		if (!is_array($cflink))
644
			$cflink = array();
645
		$cflink['interface'] = $this->GetInterface();	
646
		$cflink['name'] = $this->GetQname();
647
		$cflink['scheduler'] = $this->GetScheduler();
648
		$cflink['bandwidth'] = $this->GetBandwidth();
649
		$cflink['bandwidthtype'] = $this->GetBwscale();
650
		$cflink['qlimit'] = $this->GetQlimit();
651
		$cflink['tbrconfig'] = $this->GetTbrConfig();
652
		$cflink['enabled'] = $this->GetEnabled();
653
	}
654

    
655
}
656

    
657
class priq_queue {
658
	var $qname;
659
	var $qinterface; 
660
	var $qlimit;
661
	var $qpriority;
662
	var $description;
663
	var $isparent;
664
	var $qbandwidth;
665
	var $qbandwidthtype;
666
	var $qdefault;
667
	var $qrio;
668
	var $qred;
669
	var $qecn;
670
	var $qack;
671
	var $qenabled;
672
	var $qparent;
673
	var $link;
674
	var $available_bw; /* in b/s */
675

    
676
	/* This is here to help on form building and building rules/lists */
677
		var $subqueues = array();
678

    
679
	/* Accesor functions */
680
	function GetAvailableBandwidth() {
681
		return $this->available_bw;
682
	}
683
	function SetAvailableBandwidth($bw) {
684
		$this->available_bw = $bw;
685
	}
686
	function SetLink($link) {
687
			$this->link = $link;
688
	}
689
	function GetLink() {
690
			return $this->link;
691
	}
692
	function &GetParent() {
693
		return $this->qparent;
694
	}
695
	function SetParent(&$parent) {
696
		$this->qparent = &$parent;
697
	}
698
	function GetEnabled() {
699
			return $this->qenabled;
700
	}
701
	function SetEnabled($value) {
702
			$this->qenabled = $value;
703
	}
704
	function CanHaveChilds() {
705
			return false;
706
	}
707
	function CanBeDeleted() {
708
			return true;
709
	}
710
	function GetQname() {
711
			return $this->qname;
712
	}
713
	function SetQname($name) {
714
			$this->qname = trim($name);
715
	}
716
	function GetBandwidth() {
717
			return $this->qbandwidth;
718
	}
719
	function SetBandwidth($bandwidth) {
720
			$this->qbandwidth = $bandwidth;
721
	}
722
	function GetInterface() {
723
			return $this->qinterface;
724
	}
725
	function SetInterface($name) {
726
			$this->qinterface = trim($name);
727
	}
728
	function GetQlimit() {
729
			return $this->qlimit;
730
	}
731
	function SetQlimit($limit) {
732
			$this->qlimit = $limit;
733
	}
734
	function GetQpriority() {
735
			return $this->qpriority;
736
	}
737
	function SetQpriority($priority) {
738
			$this->qpriority = $priority;
739
	}
740
	function GetDescription() {
741
			return $this->description;
742
	}
743
	function SetDescription($str) {
744
			$this->description = trim($str);
745
	}
746
	function GetFirstime() {
747
			return $this->firsttime;
748
	}
749
	function SetFirsttime($number) {
750
			$this->firsttime = $number;
751
	}
752
	function GetBwscale() {
753
			return $this->qbandwidthtype;
754
	}
755
	function SetBwscale($scale) {
756
			$this->qbandwidthtype = $scale;
757
	}
758
	function GetDefault() {
759
			return $this->qdefault;
760
	}
761
	function SetDefault($value = false) {
762
			$this->qdefault = $value;
763
	altq_set_default_queue($this->GetInterface(), "true");
764
	}
765
	function GetRed() {
766
			return $this->qred;
767
	}
768
	function SetRed($red = false) {
769
			$this->qred = $red;
770
	}
771
	function GetRio() {
772
			return $this->qrio;
773
	}
774
	function SetRio($rio = false) {
775
			$this->qrio = $rio;
776
	}
777
function GetEcn() {
778
			return $this->qecn;
779
	}
780
	function SetEcn($ecn = false) {
781
			$this->qecn = $ecn;
782
	}
783
	function GetAck() {
784
			return $this->qack;
785
	}
786
	function SetAck($ack = false) {
787
			$this->qack = $ack;
788
	}
789

    
790
	function build_javascript() {
791
		$javascript = "<script type=\"text/javascript\">";
792
		$javascript .= "function mySuspend() { \n";
793
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null);\n";
794
		$javascript .= "document.layers['shaperarea'].visibility = 'hidden';\n";
795
		$javascript .= "else if (document.all)\n";
796
		$javascript .= "document.all['shaperarea'].style.visibility = 'hidden';\n";
797
		$javascript .= "}\n";
798

    
799
		$javascript .= "function myResume() {\n";
800
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null)\n";
801
		$javascript .= "document.layers['shaperarea'].visibility = 'visible';\n";
802
		$javascript .= "else if (document.all)\n";
803
		$javascript .= "document.all['shaperarea'].style.visibility = 'visible';\n";
804
		$javascript .= "}\n";
805
		$javascript .= "</script>";
806
		
807
		return $javascript;
808
	}
809
	
810
	/* 
811
	 * Currently this will not be called unless we decide to clonce whole 
812
	 * queue tree on the 'By Queues' view or support drag&drop on the tree/list
813
	 */
814
	 function copy_queue($interface, &$cflink) {
815

    
816
 		$cflink['name'] = $this->GetQname();
817
                $cflink['interface'] = $interface;
818
                $cflink['qlimit'] = $this->GetQlimit();
819
                $cflink['priority'] = $this->GetQpriority();
820
                $cflink['description'] = $this->GetDescription();
821
                $cflink['enabled'] = $this->GetEnabled();
822
                $cflink['default'] = $this->GetDefault();
823
                $cflink['red'] = $this->GetRed();
824
                $cflink['rio'] = $this->GetRio();
825
                $cflink['ecn'] = $this->GetEcn();
826

    
827
                if (is_array($this->subqueues)) {
828
                        $cflinkp['queue'] = array();
829
                        foreach ($this->subqueues as $q) {
830
				 $cflink['queue'][$q->GetQname()] = array();
831
                                $q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
832
			}
833
                }
834

    
835
	 }
836

    
837
	function clean_queue($sched) {
838
		clean_child_queues($sched, $this->GetLink());
839
		if (is_array($this->subqueues)) {
840
				foreach ($this->subqueues as $q)
841
						$q->clean_queue($sched);
842
				}
843
		}
844

    
845

    
846
		
847
        function &get_queue_list(&$qlist) {
848
                        $qlist[$this->GetQname()] = & $this;
849
                        if (is_array($this->subqueues)) {
850
                                foreach ($this->subqueues as $queue)
851
                                        $queue->get_queue_list($qlist);
852
                        }
853
        }
854

    
855
	function delete_queue() {
856
		unref_on_altq_queue_list($this->GetQname());
857
		if ($this->GetDefault())
858
				altq_set_default_queue($this->GetInterface(), "false");
859
		cleanup_queue_from_rules($this->GetQname());
860
		unset_object_by_reference($this->GetLink());
861
	}
862
	
863
	function delete_all() {
864
                if (count($this->subqueues)) {
865
                        foreach ($this->subqueues as $q) {
866
                                $q->delete_all();
867
                                unset_object_by_reference($q->GetLink());
868
                                unset($q);
869
                        }
870
                        unset($this->subqueues);
871
                }
872
        }
873

    
874
	 function &find_queue($interface, $qname) { 
875
		if ($qname == $this->GetQname())
876
			return $this; 
877
	}
878
	
879
	function find_parentqueue($interface, $qname) { return; }
880
		
881
	function validate_input($data, &$input_errors) {
882
	
883
		$reqfields[] = "name";
884
		$erqfieldsn[] = "Name";
885
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
886

    
887
		if ($data['priority'] && (!is_numeric($data['priority'])
888
						|| ($data['priority'] < 1) || ($data['priority'] > 15))) {
889
					$input_errors[] = "The priority must be an integer between 1 and 15.";
890
		}
891
		if ($data['qlimit'] && (!is_numeric($data['qlimit']))) 
892
				$input_errors[] = "Queue limit must be an integer";
893
		if ($data['qlimit'] < 0)
894
				$input_errors[] = "Queue limit must be positive";
895
		if (!preg_match("/^[a-zA-Z0-9_-]*$/", $data['name']))
896
			 $input_errors[] = "Queue names must be alphanumeric and _ or - only.";
897
		
898
	}
899

    
900
	function ReadConfig(&$q) {
901
		if (isset($q['name']))
902
				$this->SetQname($q['name']);
903
		if (isset($q['interface']))
904
				$this->SetInterface($q['interface']);
905
		if ($q['bandwidth'] <> "") {
906
			$this->SetBandwidth($q['bandwidth']);
907
			if ($q['bandwidthtype'] <> "")
908
				$this->SetBwscale($q['bandwidthtype']);
909
		}
910
		if (isset($q['qlimit']) && $q['qlimit'] <> "")
911
					$this->SetQlimit($q['qlimit']);
912
				if (isset($q['priority']))
913
						$this->SetQPriority($q['priority']);
914
				if (isset($q['description']) && $q['description'] != "")
915
						$this->SetDescription($q['description']);
916
		if (isset($q['ftpqueue']) && $q['ftpqueue'] <> "") 
917
			set_is_ftp_queue($this->GetInterface(), $this->GetQname());
918
		$this->SetRed($q['red']);
919
		$this->SetRio($q['rio']);
920
		$this->SetEcn($q['ecn']);
921
		$this->SetDefault($q['default']);
922
		$this->SetEnabled($q['enabled']);
923

    
924
		}
925

    
926
	function build_tree() {
927
			$tree = " <li><a href=\"firewall_shaper.php?interface=". $this->GetInterface()."&queue=". $this->GetQname()."&action=show"; 
928
			$tree .= "\" ";
929
			if ($this->GetDefault())
930
				$tree .= " class=\"navlnk\"";
931
			$tree .= " >" . $this->GetQname() . "</a>";
932
			/* 
933
			 * Not needed here!
934
			 * if (is_array($queues) {
935
			 *	  $tree .= "<ul>";
936
			 *	  foreach ($q as $queues) 
937
			 *		  $tree .= $queues['$q->GetName()']->build_tree();
938
			 *	  endforeach	
939
			 *	  $tree .= "</ul>";
940
			 * }
941
			 */
942

    
943
			$tree .= "</li>"; 
944

    
945
			return $tree;
946
		}
947
		
948
		/* Should return something like:
949
		 * queue $qname on $qinterface bandwidth ....
950
		 */
951
		function build_rules() {
952
				$pfq_rule = " queue ". $this->qname;
953
				if ($this->GetInterface())
954
						$pfq_rule .= " on ".convert_friendly_interface_to_real_interface_name($this->GetInterface());
955
				if ($this->GetQpriority())
956
						$pfq_rule .= " priority ".$this->GetQpriority();
957
				if ($this->GetQlimit())
958
						$pfq_rule .= " qlimit " . $this->GetQlimit();
959
				if ($this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetDefault()) {
960
						$pfq_rule .= " priq ( ";
961
					if ($this->GetRed()) {
962
						$comma = 1;
963
						$pfq_rule .= " red ";
964
					}
965
					if ($this->GetRio()) {
966
						if ($comma) 
967
								$pfq_rule .= " ,";
968
						$comma = 1;
969
						$pfq_rule .= " rio ";
970
					}
971
					if ($this->GetEcn()) {
972
						if ($comma) 
973
								$pfq_rule .= " ,";
974
						$comma = 1;
975
						$pfq_rule .= " ecn ";
976
					}	
977
					if ($this->GetDefault()) {
978
						if ($comma)
979
							$pfq_rule .= " ,";
980
						$pfq_rule .= " default ";
981
					}
982
					$pfq_rule .= " ) ";
983
				}
984
	
985
				$pfq_rule .= " \n";
986
		
987
				return $pfq_rule;
988
		}
989

    
990
		/*
991
		 * To return the html form to show to user
992
		 * for getting the parameters.
993
		 * Should do even for first time when the
994
		 * object is created and later when we may
995
		 * need to update it.
996
		 */
997
		function build_form() {
998
				$form .= "<tr>";
999
		$form .= "<td width=\"22%\" valign=\"top\" class=\"vncellreq\">";
1000
		$form .= "Queue Name</td><td width=\"78%\" class=\"vtable\">";
1001
		$form .= "<input name=\"name\" type=\"text\" id=\"name\" class=\"formfld unknown\" size=\"15\" maxlength=\"15\" value=\"";
1002
		$form .= htmlspecialchars($this->GetQname());
1003
		$form .= "\">";
1004
				$form .= "<br> <span class=\"vexpl\">Enter the name of the queue here.  Do not use spaces and limit the size to 15 characters.";
1005
				$form .= "</span></td>";
1006
		$form .= "</tr><tr>";
1007
				$form .= "<td width=\"22%\" valign=\"top\" class=\"vncellreq\">Priority</td>";
1008
				$form .= "<td width=\"78%\" class=\"vtable\"> <input name=\"priority\" type=\"text\" id=\"priority\" size=\"5\" value=\"";
1009
				$form .= htmlspecialchars($this->GetQpriority());
1010
				$form .= "\">";
1011
				$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>";
1012
				$form .= "</tr>";
1013
				$form .= "</tr>";
1014
				$form .= "<td width=\"22%\" valign=\"top\" class=\"vncellreq\">Queue limit</td>";
1015
				$form .= "<td width=\"78%\" class=\"vtable\"> <input name=\"qlimit\" type=\"text\" id=\"qlimit\" size=\"5\" value=\"";
1016
				$form .= htmlspecialchars($this->GetQlimit());
1017
				$form .= "\">";
1018
		$form .= "<br> <span class=\"vexpl\">Queue limit in packet per second."; 
1019
				$form .= "</span></td>";
1020
				$form .= "<tr>";
1021
				$form .= "<td width=\"22%\" valign=\"top\" class=\"vncell\">Scheduler options</td>";
1022
				$form .= "<td width=\"78%\" class=\"vtable\">";
1023
		if ($this->GetDefault()) { 
1024
				$form .= "<input type=\"checkbox\" id=\"default\" CHECKED name=\"default\"";
1025
		$form .= "> Default queue<br>";
1026
		} else {
1027
			$form .= "<input type=\"checkbox\" id=\"default\" name=\"default\"";
1028
					$form .= "> Default queue<br>";
1029
		}
1030
		/* XXX: TODO Add check to disable this if it has been set on another queue on this interface. */
1031
		$form .= "<input type=\"checkbox\" id=\"ftpqueue\" name=\"ftpqueue\" ";
1032
		if (get_is_ftp_queue($this->GetInterface(), $this->GetQname()))  
1033
			$form .= " CHECKED";
1034
		$form .= ">Use this queue for the ftp proxy<br>";
1035
		/* XXX: TODO */
1036
				$form .= "<input type=\"checkbox\" id=\"red\" name=\"red\"";
1037
				if($this->GetRed()) 
1038
			$form .=  " CHECKED";
1039
		$form .= "> <a target=\"_new\" href=\"http://www.openbsd.org/faq/pf/queueing.html#red\">Random Early Detection</a><br>";
1040
				$form .= "<input type=\"checkbox\" id=\"rio\" name=\"rio\"";
1041
				if($this->GetRio()) 
1042
			$form .=  " CHECKED";
1043
		$form .= "> <a target=\"_new\" href=\"http://www.openbsd.org/faq/pf/queueing.html#rio\">Random Early Detection In and Out</a><br>";
1044
				$form .= "<input type=\"checkbox\" id=\"ecn\" name=\"ecn\"";
1045
				if($this->GetEcn()) 
1046
			$form .=  " CHECKED";
1047
		$form .= "> <a target=\"_new\" href=\"http://www.openbsd.org/faq/pf/queueing.html#ecn\">Explicit Congestion Notification</a><br>";
1048
				$form .= "<span class=\"vexpl\"><br>Select options for this queue";
1049
				$form .= "</tr><tr>";
1050
		$form .= "<td width=\"22%\" class=\"vncellreq\">Description</td>";
1051
		$form .= "<td width=\"78%\" class=\"vtable\">";
1052
		$form .= "<input type=\"text\" name=\"description\" size=\"50%\" class=\"formfld unknown\" value=\"" . $this->GetDescription() . "\"  >";
1053
		$form .= "</td></tr>";
1054
		$form .= "<input type=\"hidden\" name=\"interface\" id=\"interface\"";
1055
				$form .= " value=\"".$this->GetInterface()."\">";
1056

    
1057
		return $form;
1058
		}
1059

    
1060
	function build_shortform() {
1061
		/* XXX: Hacks in site. Mostly layer violations!  */
1062
		global $g, $altq_list_queues;
1063

    
1064
		$altq =& $altq_list_queues[$this->GetInterface()];
1065
		if ($altq)
1066
			$scheduler = ": " . $altq->GetScheduler();
1067
		 $form = "<tr><td width=\"20%\" class=\"vtable\">";
1068
		$form .= "<a href=\"firewall_shaper.php?interface" . $this->GetInterface() . "&queue=" . $this->GetInterface()."&action=show\">".$this->GetInterface().": ".$scheduler."</a>";
1069
		$form .= "</td></tr>";
1070
		/* 
1071
		 * XXX: Hack in sight maybe fix with a class that wraps all
1072
		 * of this layer violations
1073
		 */
1074
		$form .= "<tr>";
1075
		$form .= "<td width=\"50%\" class=\"vncellreq\">";
1076
		$form .= "Bandwidth: " . $this->GetBandwidth().$this->GetBwscale();
1077
		$form .= "</td><td width=\"50%\"></td></tr>";
1078
		$form .= "<tr><td width=\"20%\" class=\"vncellreq\">";
1079
		if ($this->GetQpriority())
1080
			$form .= "Priority: on </td></tr>";
1081
		if ($this->GetDefault())
1082
			$form .= "<tr><td class=\"vncellreq\">Default: on </td></tr>";
1083
		$form .= "<tr><td width=\"20%\" class=\"vncellreq\">";
1084
		$form .= "<a href=\"firewall_shaper_queues.php?interface=";
1085
			$form .= $this->GetInterface() . "&queue=";
1086
			$form .= $this->GetQname() . "&action=delete\">";
1087
			$form .= "<img src=\"";
1088
			$form .= "./themes/".$g['theme']."/images/icons/icon_x.gif\"";
1089
			$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Delete queue from interface\">";
1090
			$form .= "<span>Delete queue from interface</span></a></td></tr>";
1091
		
1092
		return $form;
1093

    
1094
	}
1095

    
1096
		function update_altq_queue_data(&$q) { 
1097
		$this->ReadConfig($q);
1098
	}
1099

    
1100
		function wconfig() {
1101
				$cflink =& get_reference_to_me_in_config($this->GetLink());
1102
		if (!is_array($cflink))
1103
			$cflink = array();
1104
		$cflink['name'] = $this->GetQname();
1105
				$cflink['interface'] = $this->GetInterface();
1106
				$cflink['qlimit'] = $this->GetQlimit();
1107
				$cflink['priority'] = $this->GetQpriority();
1108
		$cflink['description'] = $this->GetDescription();
1109
		$cflink['enabled'] = $this->GetEnabled();
1110
		$cflink['default'] = $this->GetDefault();
1111
		$cflink['red'] = $this->GetRed();
1112
		$cflink['rio'] = $this->GetRio();
1113
		$cflink['ecn'] = $this->GetEcn();
1114
	}
1115
}
1116

    
1117
class hfsc_queue extends priq_queue {
1118
		/* realtime */
1119
	var $realtime;
1120
		var $r_m1;
1121
		var $r_d;
1122
		var $r_m2;
1123
		/* linkshare */
1124
	var $linkshare;
1125
		var $l_m1;
1126
		var $l_d;
1127
		var $l_m2;
1128
		/* upperlimit */
1129
	var $upperlimit;
1130
		var $u_m1;
1131
		var $u_d;
1132
		var $u_m2;
1133

    
1134
		/*
1135
		 * HFSC can have nested queues.
1136
		 */
1137

    
1138
	function CanHaveChilds() {
1139
				return true;
1140
		}
1141
	function GetRealtime() {
1142
           return $this->realtime;
1143
     }
1144
     function GetR_m1() {
1145
           return $this->r_m1;
1146
     }
1147
     function GetR_d() {
1148
           return $this->r_d;
1149
     }
1150
     function GetR_m2() {
1151
           return $this->r_m2;
1152
     }
1153
     function SetRealtime() {
1154
           $this->realtime = "on";
1155
     }
1156
     function DisableRealtime() {
1157
           $this->realtime = "";
1158
     }
1159
     function SetR_m1($value) {
1160
           $this->r_m1 = $value;
1161
     }
1162
     function SetR_d($value) {
1163
           $this->r_d = $value;
1164
     }
1165
     function SetR_m2($value) {
1166
           $this->r_m2 = $value;
1167
     }
1168
     function GetLinkshare() {
1169
           return $this->linkshare;
1170
     }
1171
     function DisableLinkshare() {
1172
           $this->linkshare = "";
1173
     }
1174
     function GetL_m1() {
1175
           return $this->l_m1;
1176
     }
1177
     function GetL_d() {
1178
           return $this->l_d;
1179
     }
1180
     function GetL_m2() {
1181
           return $this->l_m2;
1182
     }
1183
     function SetLinkshare() {
1184
           $this->linkshare = "on";
1185
     }
1186
     function SetL_m1($value) {
1187
           $this->l_m1 = $value;
1188
     }
1189
     function SetL_d($value) {
1190
           $this->l_d = $value;
1191
     }
1192
     function SetL_m2($value) {
1193
           $this->l_m2 = $value;
1194
     }
1195
     function GetUpperlimit() {
1196
           return $this->upperlimit;
1197
     }
1198
     function GetU_m1() {
1199
           return $this->u_m1;
1200
     }
1201
     function GetU_d() {
1202
           return $this->u_d;
1203
     }
1204
     function GetU_m2() {
1205
           return $this->u_m2;
1206
     }
1207
     function SetUpperlimit() {
1208
           $this->upperlimit = "on";
1209
     }
1210
     function DisableUpperlimit() {
1211
           $this->upperlimit = "";
1212
     }
1213
     function SetU_m1($value) {
1214
           $this->u_m1 = $value;
1215
     }
1216
     function SetU_d($value) {
1217
           $this->u_d = $value;
1218
     }
1219
     function SetU_m2($value) {
1220
           $this->u_m2 = $value;
1221
     }
1222

    
1223

    
1224

    
1225
		function &add_queue($interface, &$qname, &$path, &$input_errors) {
1226

    
1227
			if (!is_array($this->subqueues))
1228
							$this->subqueues = array();
1229
			$q =& new hfsc_queue();
1230
			$q->SetInterface($this->GetInterface());
1231
			$q->SetParent(&$this);
1232
			$q->ReadConfig($qname);
1233
			$q->validate_input($qname, $input_errors);
1234
			if (count($input_errors)) {
1235
				return $q;
1236
			}
1237
			
1238
			$q->SetEnabled("on");
1239
			$q->SetLink($path);
1240
			switch ($q->GetBwscale()) {
1241
                        case "%":
1242
                                $myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
1243
                                break;
1244
                        default:
1245
                                $myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
1246
                                break;
1247
                	}
1248
                        $q->SetAvailableBandwidth($myBw);
1249
                        $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
1250

    
1251
			$this->subqueues[$q->GetQname()] =& $q; //new hfsc_queue()
1252
			ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
1253
			if (is_array($qname['queue'])) {
1254
				foreach ($qname['queue'] as $key1 => $que) {
1255
					array_push($path, $key1);
1256
								$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
1257
					array_pop($path);
1258
				}
1259
					}
1260
	
1261
			return $q;
1262
		}
1263

    
1264
 	        function copy_queue($interface, &$cflink) {
1265

    
1266
                        $cflink['name'] = $this->GetQname();
1267
                        $cflink['interface'] = $interface;
1268
                        $cflink['qlimit'] = $this->GetQlimit();
1269
                        $cflink['priority'] = $this->GetQpriority();
1270
                        $cflink['description'] = $this->GetDescription();
1271
                        $cflink['bandwidth'] = $this->GetBandwidth();
1272
                        $cflink['bandwidthtype'] = $this->GetBwscale();
1273
                        $cflink['enabled'] = $this->GetEnabled();
1274
                        $cflink['default'] = $this->GetDefault();
1275
                        $cflink['red'] = $this->GetRed();
1276
                        $cflink['rio'] = $this->GetRio();
1277
                        $cflink['ecn'] = $this->GetEcn();
1278
                        if ($this->GetLinkshare() <> "") {
1279
                                if ($this->GetL_m1() <> "") {
1280
                                        $cflink['linkshare1'] = $this->GetL_m1();
1281
                                        $cflink['linkshare2'] = $this->GetL_d();
1282
                                        $cflink['linkshare'] = "on";
1283
                                }
1284
                                if ($this->GetL_m2() <> "") {
1285
                                        $cflink['linkshare3'] = $this->GetL_m2();
1286
                                        $cflink['linkshare'] = "on";
1287
                                }
1288
                        } else $cflink['linkshare'] = "";
1289
                        if ($this->GetRealtime() <> "") {
1290
                                if ($this->GetR_m1() <> "") {
1291
                                        $cflink['realtime1'] = $this->GetR_m1();
1292
                                        $cflink['realtime2'] = $this->GetR_d();
1293
                                        $cflink['realtime'] = "on";
1294
                                }
1295
                                if ($this->GetR_m2() <> "") {
1296
                                        $cflink['realtime3'] = $this->GetR_m2();
1297
                                        $cflink['realtime'] = "on";
1298
                                }
1299
                        } else $cflink['realtime'] = "";
1300
                        if ($this->GetUpperlimit() <> "") {
1301
                                if ($this->GetU_m1() <> "") {
1302
                                        $cflink['upperlimit1'] = $this->GetU_m1();
1303
                                        $cflink['upperlimit2'] = $this->GetU_d();
1304
                                        $cflink['upperlimit'] = "on";
1305
                                }
1306
                                if ($this->GetU_m2() <> "") {
1307
                                        $cflink['upperlimit3'] = $this->GetU_m2();
1308
                                        $cflink['upperlimit'] = "on";
1309
                                }
1310
                        } else $cflink['upperlimit'] = "";
1311

    
1312
	                if (is_array($this->subqueues)) {
1313
        	                $cflinkp['queue'] = array();
1314
                	        foreach ($this->subqueues as $q) {
1315
                	                 $cflink['queue'][$q->GetQname()] = array();
1316
        	                        $q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
1317
				}
1318
                	}
1319

    
1320
         	}
1321

    
1322
		function delete_queue() { 
1323
			unref_on_altq_queue_list($this->GetQname());
1324
			if ($this->GetDefault()) 
1325
				altq_set_default_queue($this->GetInterface(), "false");
1326
			cleanup_queue_from_rules($this->GetQname());
1327
			$parent =& $this->GetParent();
1328
			foreach ($this->subqueues as $q)  {
1329
			$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
1330
				$q->delete_queue();
1331
			}
1332
			unset_object_by_reference($this->GetLink());
1333
			}
1334
	
1335
			/*
1336
			 * Should search even its childs
1337
			 */
1338
			function &find_queue($interface, $qname) {
1339
					if ($qname == $this->GetQname()) 
1340
							return $this;
1341
		
1342
					foreach ($this->subqueues as $q) {
1343
							$result =& $q->find_queue("", $qname);
1344
				if ($result)
1345
									return $result;
1346
					}
1347
			}
1348

    
1349
	function &find_parentqueue($interface, $qname) {
1350
		if ($this->subqueues[$qname]) 
1351
			return $this;
1352
				foreach ($this->subqueues as $q) {
1353
					$result = $q->find_parentqueue("", $qname);
1354
			if ($result)
1355
				return $result;
1356
		}
1357
		}
1358
	
1359
	function validate_input($data, &$input_errors) {
1360
		parent::validate_input($data, $input_errors);
1361
		
1362
		$reqfields[] = "bandwidth";
1363
		$reqdfieldsn[] = "Bandwidth";
1364
		$reqfields[] = "bandwidthtype";
1365
		$reqdfieldsn[] = "Bandwidthtype";
1366

    
1367
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
1368
		
1369
		if (isset($data['linkshare3']) && $data['linkshare3'] <> "") {
1370
		if ($data['bandwidth'] && (!is_numeric($data['bandwidth'])))
1371
                        $input_errors[] = "Bandwidth must be an integer.";
1372

    
1373
                if ($data['bandwidth'] < 0)
1374
                        $input_errors[] = "Bandwidth cannot be negative.";
1375

    
1376
                if ($data['bandwidthtype'] == "%") {
1377
                 if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
1378
                       $input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
1379
                 }
1380
/*
1381
                $parent =& $this->GetParent();
1382
                switch ($data['bandwidthtype']) {
1383
                       case "%":
1384
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
1385
                       default:
1386
                             $mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
1387
                             break;
1388
                }
1389
                if ($parent->GetAvailableBandwidth() < $myBw)
1390
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
1391
*/
1392
                if ($data['priority'] > 7)
1393
                        $input_errors[] = "Priority must be an integer between 1 and 7.";
1394
		}
1395

    
1396
		if ($data['upperlimit1'] <> "" &&  $data['upperlimit2'] == "")
1397
			$input_errors[] = ("upperlimit service curve defined but missing (d) value");
1398
		if ($data['upperlimit2'] <> "" &&  $data['upperlimit1'] == "")
1399
			$input_errors[] = ("upperlimit service curve defined but missing initial bandwidth (m1) value");
1400
		if ($data['upperlimit1'] <> "" && !is_valid_shaperbw($data['upperlimit1']))
1401
			$input_errors[] = ("upperlimit m1 value needs to be Kb, Mb, Gb, or %");
1402
		if ($data['upperlimit2'] <> "" && !is_numeric($data['upperlimit2']))
1403
			$input_errors[] = ("upperlimit d value needs to be numeric");
1404
		if ($data['upperlimit3'] <> "" && !is_valid_shaperbw($data['upperlimit3']))
1405
			$input_errors[] = ("upperlimit m2 value needs to be Kb, Mb, Gb, or %");
1406
/*
1407

    
1408
		if (isset($data['upperlimit']) && $data['upperlimit3'] <> "" && $data['upperlimit1'] <> "") {
1409
		$bw_1 = get_hfsc_bandwidth($this, $data['upperlimit1']);
1410
		$bw_2 = get_hfsc_bandwidth($this, $data['upperlimit3']);
1411
		if (floatval($bw_1) < floatval($bw_2)) 
1412
			$input_errors[] = ("upperlimit m1 cannot be smaller than m2");
1413

    
1414
		
1415
		if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1416
			$input_errors[] = ("upperlimit specification excedd 80% of allowable allocation.");
1417
		}
1418
*/
1419
		if ($data['linkshare1'] <> "" &&  $data['linkshare2'] == "")
1420
			$input_errors[] = ("linkshare service curve defined but missing (d) value");
1421
		if ($data['linkshare2'] <> "" &&  $data['linkshare1'] == "")
1422
			$input_errors[] = ("linkshare service curve defined but missing initial bandwidth (m1) value");
1423
		if ($data['linkshare1'] <> "" && !is_valid_shaperbw($data['linkshare1']))
1424
			$input_errors[] = ("linkshare m1 value needs to be Kb, Mb, Gb, or %");
1425
		if ($data['linkshare2'] <> "" && !is_numeric($data['linkshare2']))
1426
			$input_errors[] = ("linkshare d value needs to be numeric");
1427
		if ($data['linkshare3'] <> "" && !is_valid_shaperbw($data['linkshare3']))
1428
			$input_errors[] = ("linkshare m2 value needs to be Kb, Mb, Gb, or %");
1429
		if ($data['realtime1'] <> "" &&  $data['realtime2'] == "")
1430
			$input_errors[] = ("realtime service curve defined but missing (d) value");
1431
		if ($data['realtime2'] <> "" &&  $data['realtime1'] == "")
1432
			$input_errors[] = ("realtime service curve defined but missing initial bandwidth (m1) value");
1433

    
1434
/*
1435
		if (isset($data['linkshare']) && $data['linkshare3'] <> "" && $data['linkshare1'] <> "" && 0) {
1436
		$bw_1 = get_hfsc_bandwidth($this, $data['linkshare1']);
1437
                $bw_2 = get_hfsc_bandwidth($this, $data['linkshare3']);
1438
                if (floatval($bw_1) < floatval($bw_2))
1439
                        $input_errors[] = ("linkshare m1 cannot be smaller than m2");
1440

    
1441

    
1442
                if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1443
                        $input_errors[] = ("linkshare specification excedd 80% of allowable allocation.");
1444
		}
1445
*/
1446

    
1447
		if ($data['realtime1'] <> "" && !is_valid_shaperbw($data['realtime1']))
1448
			$input_errors[] = ("realtime m1 value needs to be Kb, Mb, Gb, or %");
1449
		if ($data['realtime2'] <> "" && !is_numeric($data['realtime2']))
1450
			$input_errors[] = ("realtime d value needs to be numeric");
1451
		if ($data['realtime3'] <> "" && !is_valid_shaperbw($data['realtime3']))
1452
			$input_errors[] = ("realtime m2 value needs to be Kb, Mb, Gb, or %");
1453

    
1454
/*
1455
		if (isset($data['realtime']) && $data['realtime3'] <> "" && $data['realtime1'] <> "" && 0) {
1456
		$bw_1 = get_hfsc_bandwidth($this, $data['realtime1']);
1457
                $bw_2 = get_hfsc_bandwidth($this, $data['realtime3']);
1458
                if (floatval($bw_1) < floatval($bw_2))
1459
                        $input_errors[] = ("realtime m1 cannot be smaller than m2");
1460

    
1461

    
1462
                if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1463
                        $input_errors[] = ("realtime specification excedd 80% of allowable allocation.");
1464
		}
1465
*/
1466

    
1467
	}
1468

    
1469
		function ReadConfig(&$cflink) {
1470
		if (isset($cflink['linkshare']) && $cflink['linkshare'] <> "") {
1471
			if (isset($cflink['linkshare1']) && $cflink['linkshare1'] <> "") {
1472
				$this->SetL_m1($cflink['linkshare1']);
1473
                                $this->SetL_d($cflink['linkshare2']);
1474
				$this->SetLinkshare();
1475
			}
1476
			if (isset($cflink['linkshare3']) && $cflink['linkshare3'] <> "") {
1477
                                $this->SetL_m2($cflink['linkshare3']);
1478
				$this->SetLinkshare();
1479
			}
1480
		} else $this->DisableLinkshare();
1481
		if (isset($cflink['realtime']) && $cflink['realtime'] <> "") {
1482
                        if (isset($cflink['realtime1']) && $cflink['realtime1'] <> "") {
1483
                                $this->SetR_m1($cflink['realtime1']);
1484
                                $this->SetR_d($cflink['realtime2']);
1485
				$this->SetRealtime();
1486
			}
1487
                        if (isset($cflink['realtime3']) && $cflink['realtime3'] <> "") {
1488
                                $this->SetR_m2($cflink['realtime3']);
1489
				$this->SetRealtime();
1490
			}
1491
		} else $this->DisableRealtime(); 
1492
		if (isset($cflink['upperlimit']) && $cflink['upperlimit'] <> "") {
1493
                        if (isset($cflink['upperlimit1']) && $cflink['upperlimit1'] <> "") {
1494
                                $this->SetU_m1($cflink['upperlimit1']);
1495
                                $this->SetU_d($cflink['upperlimit2']);
1496
				$this->SetUpperlimit();
1497
			}
1498
                        if (isset($cflink['upperlimit3']) && $cflink['upperlimit3'] <> "") {
1499
                                $this->SetU_m2($cflink['upperlimit3']);
1500
				$this->SetUpperlimit();
1501
			}
1502
		} else $this->DisableUpperlimit();
1503
		parent::ReadConfig($cflink);
1504

    
1505
		}
1506

    
1507
	function build_tree() {
1508
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface() ."&queue=" . $this->GetQname()."&action=show"; 
1509
		$tree .= "\" ";
1510
		if ($this->GetDefault())
1511
								$tree .= " class=\"navlnk\"";
1512
		$tree .= " >" . $this->GetQname() . "</a>";
1513
		if (is_array($this->subqueues)) {
1514
			$tree .= "<ul>";
1515
			foreach ($this->subqueues as $q)  {
1516
				$tree .= $q->build_tree();
1517
			}	
1518
			$tree .= "</ul>";
1519
		}
1520
		$tree .= "</li>";
1521
		return $tree;
1522
	}
1523

    
1524
		/* Even this should take childs in consideration */
1525
		function build_rules() {
1526

    
1527
				$pfq_rule = " queue ". $this->qname;
1528
				if ($this->GetInterface())
1529
						$pfq_rule .= " on ".convert_friendly_interface_to_real_interface_name($this->GetInterface());
1530
		if ($this->GetBandwidth() && $this->GetBwscale())
1531
						$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
1532
					
1533
				if ($this->GetQpriority())
1534
						$pfq_rule .= " priority " . $this->GetQpriority();
1535
				if ($this->GetQlimit())
1536
						$pfq_rule .= " qlimit " . $this->GetQlimit();
1537
		  if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetRealtime() <> "" || $this->GetLinkshare() <> "" || $this->GetUpperlimit() <> "") {
1538
						$pfq_rule .= " hfsc ( ";
1539
						if ($this->GetRed()) {
1540
								$comma = 1;
1541
								$pfq_rule .= " red ";
1542
						}
1543
						if ($this->GetRio()) {
1544
								if ($comma) 
1545
										$pfq_rule .= " ,";
1546
								$comma = 1;
1547
								$pfq_rule .= " rio ";
1548
						}
1549
						if ($this->GetEcn()) {
1550
								if ($comma) 
1551
										$pfq_rule .= " ,";
1552
								$comma = 1;
1553
								$pfq_rule .= " ecn ";
1554
						}
1555
						if ($this->GetDefault()) {
1556
								if ($comma)
1557
										$pfq_rule .= " ,";
1558
								$comma = 1;
1559
								$pfq_rule .= " default ";
1560
						}
1561

    
1562
						if ($this->GetRealtime() <> "")  {
1563
				if ($comma) 
1564
									$pfq_rule .= " , ";
1565
				if ($this->GetR_m1()  <> "" && $this->GetR_d() <> "" && $this->GetR_m2() <> "")
1566
			$pfq_rule .= " realtime (".$this->GetR_m1() . ", " . $this->GetR_d().", ". $this->GetR_m2() .") ";
1567
				else  if ($this->GetR_m2() <> "")
1568
					$pfq_rule .= " realtime " . $this->GetR_m2();
1569
				$comma = 1;
1570
			}
1571
						if ($this->GetLinkshare() <> "") {
1572
								if ($comma)
1573
					$pfq_rule .= " ,";
1574
				if ($this->GetL_m1() <> "" && $this->GetL_d() <> "" && $this->GetL_m2() <> "")
1575
			$pfq_rule .= " linkshare (".$this->GetL_m1(). ", ". $this->GetL_d(). ", ". $this->GetL_m2(). ") ";
1576
				else if ($this->GetL_m2() <> "")
1577
					$pfq_rule .= " linkshare " . $this->GetL_m2() . " ";
1578
				$comma = 1;
1579
			}
1580
						if ($this->GetUpperlimit() <> "") {
1581
				if ($comma)
1582
					$pfq_rule .= " ,";
1583
				if ($this->GetU_m1() <> "" && $this->GetU_d() <> "" && $this->GetU_m2() <> "")
1584
							$pfq_rule .= " upperlimit (".$this->GetU_m1().", ". $this->GetU_d().", ". $this->GetU_m2(). ") ";
1585
				else if ($this->GetU_m2() <> "")
1586
					$pfq_rule .= " upperlimit " . $this->GetU_m2() . " ";
1587
			}
1588
					$pfq_rule .= " ) ";
1589
					}
1590
					if (count($this->subqueues)) {
1591
						$i = count($this->subqueues);
1592
						$pfq_rule .= " { ";
1593
						foreach ($this->subqueues as $qkey => $qnone) {
1594
								if ($i > 1) {
1595
										$i--;
1596
										$pfq_rule .= " {$qkey}, ";
1597
								} else
1598
										$pfq_rule .= " {$qkey} ";
1599
						}
1600
								$pfq_rule .= " } \n";
1601
								foreach ($this->subqueues as $q)
1602
									$pfq_rule .= $q->build_rules();
1603
					}
1604

    
1605
				 $pfq_rule .= " \n";
1606
			
1607
				return $pfq_rule;
1608
		}
1609

    
1610
	function build_javascript() {
1611
		$javascript = parent::build_javascript();
1612
		$javascript .= "<script type=\"text/javascript\">";
1613
		$javascript .= "function enable_realtime(enable_over) { \n";
1614
		$javascript .= "if (document.iform.realtime.checked || enable_over) { \n";
1615
		$javascript .= "document.iform.realtime1.disabled = 0;\n";
1616
		$javascript .= "document.iform.realtime2.disabled = 0;\n";
1617
		$javascript .= "document.iform.realtime3.disabled = 0;\n";
1618
		$javascript .= " } else { \n";
1619
		$javascript .= "document.iform.realtime1.disabled = 1;\n";
1620
		$javascript .= "document.iform.realtime2.disabled = 1;\n";
1621
		$javascript .= "document.iform.realtime3.disabled = 1;\n";
1622
		$javascript .= " } \n";
1623
		$javascript .= " } \n";
1624
		$javascript .= "function enable_linkshare(enable_over) { \n";
1625
		$javascript .= "if (document.iform.linkshare.checked || enable_over) { \n";
1626
		$javascript .= "document.iform.linkshare1.disabled = 0;\n";
1627
		$javascript .= "document.iform.linkshare2.disabled = 0;\n";
1628
		$javascript .= "document.iform.linkshare3.disabled = 0;\n";
1629
		$javascript .= " } else { \n";
1630
		$javascript .= "document.iform.linkshare1.disabled = 1;\n";
1631
		$javascript .= "document.iform.linkshare2.disabled = 1;\n";
1632
		$javascript .= "document.iform.linkshare3.disabled = 1;\n";
1633
		$javascript .= " } \n";
1634
		$javascript .= " } \n";
1635
		$javascript .= "function enable_upperlimit(enable_over) { \n";
1636
		$javascript .= "if (document.iform.upperlimit.checked || enable_over) { \n";
1637
		$javascript .= "document.iform.upperlimit1.disabled = 0;\n";
1638
		$javascript .= "document.iform.upperlimit2.disabled = 0;\n";
1639
		$javascript .= "document.iform.upperlimit3.disabled = 0;\n";
1640
		$javascript .= " } else { \n";
1641
		$javascript .= "document.iform.upperlimit1.disabled = 1;\n";
1642
		$javascript .= "document.iform.upperlimit2.disabled = 1;\n";
1643
		$javascript .= "document.iform.upperlimit3.disabled = 1;\n";
1644
		$javascript .= " } \n";
1645
			
1646
		$javascript .= "} \n";
1647
		$javascript .= "</script>";
1648

    
1649
		return $javascript;
1650
	}
1651

    
1652
		function build_form() {
1653
				$form = "<tr>";
1654
				$form .= "<td valign=\"top\" class=\"vncellreq\">Bandwidth</td>";
1655
				$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
1656
				$form .= htmlspecialchars($this->GetBandwidth());
1657
				$form .= "\">";
1658
				$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
1659
				$form .= "<option value=\"Gb\"";
1660
				if ($this->GetBwscale() == "Gb")
1661
						$form .= " selected=\"yes\"";
1662
				$form .= ">Gbit/s</option>";
1663
				$form .= "<option value=\"Mb\"";
1664
				if ($this->GetBwscale() == "Mb")
1665
						$form .= " selected=\"yes\"";
1666
				$form .= ">Mbit/s</option>";
1667
				$form .= "<option value=\"Kb\"";
1668
				if ($this->GetBwscale() == "Kb")
1669
						$form .= " selected=\"yes\"";
1670
				$form .= ">Kbit/s</option>";
1671
				$form .= "<option value=\"\"";
1672
				if ($this->GetBwscale() == "b")
1673
						$form .= " selected=\"yes\"";
1674
				$form .= ">Bit/s</option>";
1675
				$form .= "<option value=\"%\"";
1676
				if ($this->GetBwscale() == "%")
1677
						$form .= " selected=\"yes\"";
1678
				$form .= ">%</option>";
1679
				$form .= "</select> <br>";
1680
				$form .= "<span class=\"vexpl\">Choose the amount of bandwidth for this queue";
1681
				$form .= "</span></td>";
1682
				$form .= parent::build_form();
1683
				$form .= "<tr>";
1684
				$form .= "<td width=\"22%\" valign=\"top\" class=\"vncellreq\">Service Curve (sc)</td>";
1685
				$form .= "<td width=\"78%\" class=\"vtable\">";
1686
				$form .= "<table>";
1687
				$form .= "<tr><td>&nbsp;</td><td><center>m1</center></td><td><center>d</center></td><td><center><b>m2</b></center></td></tr>";
1688
				$form .= "<tr><td><input type=\"checkbox\" id=\"upperlimit\" name=\"upperlimit\"";
1689
				if($this->GetUpperlimit()<> "") 
1690
					$form .=  " CHECKED ";
1691
				$form .= "onChange=\"enable_upperlimit()\"> Upperlimit:</td><td><input size=\"6\" value=\"";
1692
				$form .= htmlspecialchars($this->GetU_m1());
1693
				$form .= "\" id=\"upperlimit1\" name=\"upperlimit1\" ";
1694
				if ($this->GetUpperlimit() == "") $form .= " disabled";
1695
				$form .= "></td><td><input size=\"6\" value=\"";
1696
				$form .= htmlspecialchars($this->GetU_d());
1697
				$form .= "\" id=\"upperlimi2\" name=\"upperlimit2\" ";
1698
		if ($this->GetUpperlimit() == "") $form .= " disabled";
1699
		$form .= "></td><td><input size=\"6\" value=\"";
1700
				$form .= htmlspecialchars($this->GetU_m2());
1701
				$form .= "\" id=\"upperlimit3\" name=\"upperlimit3\" ";
1702
		if ($this->GetUpperlimit() == "") $form .= " disabled";
1703
		$form .= "></td><td>The maximum allowed bandwidth for the queue.</td></tr>";
1704
				$form .= "<tr><td><input type=\"checkbox\" id=\"realtime\" name=\"realtime\"";
1705
				if($this->GetRealtime() <> "") 
1706
			$form .=  " CHECKED ";
1707
				$form .= "onChange=\"enable_realtime()\"> Real time:</td><td><input size=\"6\" value=\"";
1708
				$form .= htmlspecialchars($this->GetR_m1());
1709
				$form .= "\" id=\"realtime1\" name=\"realtime1\" ";
1710
		if ($this->GetRealtime() == "") $form .= " disabled";
1711
		$form .= "></td><td><input size=\"6\" value=\"";
1712
				$form .= htmlspecialchars($this->GetR_d());
1713
				$form .= "\" id=\"realtime2\" name=\"realtime2\" ";
1714
		if ($this->GetRealtime() == "") $form .= " disabled";
1715
		$form .= "></td><td><input size=\"6\" value=\"";
1716
				$form .= htmlspecialchars($this->GetR_m2());
1717
				$form .= "\" id=\"realtime3\" name=\"realtime3\" ";
1718
		if ($this->GetRealtime() == "") $form .= " disabled";
1719
		$form .= "></td><td>The minimum required bandwidth for the queue.</td></tr>";
1720
				$form .= "<tr><td><input type=\"checkbox\" id=\"linkshare\" id=\"linkshare\" name=\"linkshare\"";
1721
				if($this->GetLinkshare() <> "") 
1722
			$form .=  " CHECKED ";
1723
				$form .= "onChange=\"enable_linkshare()\"> Link share:</td><td><input size=\"6\" value=\"";
1724
				$form .= htmlspecialchars($this->GetL_m1());
1725
				$form .= "\" id=\"linkshare1\" name=\"linkshare1\" ";
1726
		if ($this->GetLinkshare() == "") $form .= " disabled";
1727
		$form .= "></td><td><input size=\"6\" value=\"";
1728
				$form .= htmlspecialchars($this->GetL_d());
1729
				$form .= "\" id=\"linkshare2\" name=\"linkshare2\" ";
1730
		if ($this->GetLinkshare() == "") $form .= " disabled";
1731
		$form .= "></td><td><input size=\"6\" value=\"";
1732
				$form .= htmlspecialchars($this->GetL_m2());
1733
				$form .= "\" id=\"linkshare3\" name=\"linkshare3\" ";
1734
		if ($this->GetLinkshare() == "") $form .= " disabled";
1735
		$form .= "></td><td>The bandwidth share of a backlogged queue - this overrides priority.</td></tr>";
1736
				$form .= "</table><br>";
1737
				$form .= "The format for service curve specifications is (m1, d, m2).  m2 controls";
1738
				$form .= "the bandwidth assigned to the queue.  m1 and d are optional and can be";
1739
				$form .= "used to control the initial bandwidth assignment.  For the first d milliseconds the queue gets the bandwidth given as m1, afterwards the value";
1740
				$form .= "given in m2.";
1741
				$form .= "</span></td>";
1742
				$form .= "</tr>";
1743

    
1744
				return $form;
1745
		}
1746

    
1747
	function update_altq_queue_data(&$data) { 
1748
		$this->ReadConfig($data);
1749
	}
1750

    
1751
	function wconfig() {
1752
		$cflink =& get_reference_to_me_in_config($this->GetLink());
1753
		if (!is_array($cflink))
1754
			$cflink = array();
1755
			$cflink['name'] = $this->GetQname();
1756
			$cflink['interface'] = $this->GetInterface();
1757
			$cflink['qlimit'] = $this->GetQlimit();
1758
			$cflink['priority'] = $this->GetQpriority();
1759
			$cflink['description'] = $this->GetDescription();
1760
			$cflink['bandwidth'] = $this->GetBandwidth();
1761
			$cflink['bandwidthtype'] = $this->GetBwscale();
1762
			$cflink['enabled'] = $this->GetEnabled();
1763
			$cflink['default'] = $this->GetDefault();
1764
			$cflink['red'] = $this->GetRed();
1765
			$cflink['rio'] = $this->GetRio();
1766
			$cflink['ecn'] = $this->GetEcn();
1767
			if ($this->GetLinkshare() <> "") {
1768
				if ($this->GetL_m1() <> "") {
1769
					$cflink['linkshare1'] = $this->GetL_m1();
1770
					$cflink['linkshare2'] = $this->GetL_d();
1771
					$cflink['linkshare'] = "on";
1772
				}
1773
				if ($this->GetL_m2() <> "") {
1774
					$cflink['linkshare3'] = $this->GetL_m2();
1775
					$cflink['linkshare'] = "on";
1776
				}
1777
			} else $cflink['linkshare'] = "";
1778
			if ($this->GetRealtime() <> "") {
1779
				if ($this->GetR_m1() <> "") {
1780
					$cflink['realtime1'] = $this->GetR_m1();
1781
					$cflink['realtime2'] = $this->GetR_d();
1782
					$cflink['realtime'] = "on";
1783
				}
1784
				if ($this->GetR_m2() <> "") {
1785
					$cflink['realtime3'] = $this->GetR_m2();
1786
					$cflink['realtime'] = "on";
1787
				}
1788
			} else $cflink['realtime'] = "";
1789
			if ($this->GetUpperlimit() <> "") {
1790
				if ($this->GetU_m1() <> "") {
1791
					$cflink['upperlimit1'] = $this->GetU_m1();
1792
					$cflink['upperlimit2'] = $this->GetU_d();
1793
					$cflink['upperlimit'] = "on";
1794
				}
1795
				if ($this->GetU_m2() <> "") {
1796
					$cflink['upperlimit3'] = $this->GetU_m2();
1797
					$cflink['upperlimit'] = "on";
1798
				}
1799
			} else $cflink['upperlimit'] = "";
1800
		}
1801
	}
1802

    
1803
class cbq_queue extends priq_queue {
1804
		var $qborrow;
1805

    
1806
	function GetBorrow() {
1807
		return $this->qborrow;
1808
	}
1809
	function SetBorrow($borrow) {
1810
		$this->qborrow = $borrow;
1811
	}
1812
	function CanHaveChilds() {
1813
			return true;
1814
	}
1815

    
1816
	function &add_queue($interface, &$qname, &$path, &$input_errors) {
1817

    
1818
		if (!is_array($this->subqueues))
1819
						$this->subqueues = array();
1820
		$q =& new cbq_queue();
1821
		$q->SetInterface($this->GetInterface());
1822
		$q->SetParent(&$this);
1823
		$q->ReadConfig($qname);
1824
                $q->validate_input($qname, $input_errors);
1825
                if (count($input_errors)) {
1826
                        return $q;
1827
                }
1828
                switch ($q->GetBwscale()) {
1829
                        case "%":
1830
                                $myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
1831
                                break;
1832
                        default:
1833
                                $myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
1834
                                break;
1835
                }
1836
                $q->SetAvailableBandwidth($myBw);
1837
                $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
1838

    
1839
		$q->SetEnabled("on");
1840
		$q->SetLink($path);
1841
		$this->subqueues[$q->GetQName()] = &$q;
1842
		ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
1843
		if (is_array($qname['queue'])) {
1844
				foreach ($qname['queue'] as $key1 => $que) {
1845
						array_push($path, $key1);
1846
						$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
1847
						array_pop($path);
1848
				}
1849
		}
1850

    
1851
		return $q;
1852
		}
1853

    
1854
		function copy_queue($interface, &$cflink) {
1855

    
1856
                                $cflink['interface'] = $interface;
1857
                                $cflink['qlimit'] = $this->GetQlimit();
1858
                                $cflink['priority'] = $this->GetQpriority();
1859
                                $cflink['name'] = $this->GetQname();
1860
                                $cflink['description'] = $this->GetDescription();
1861
                                $cflink['bandwidth'] = $this->GetBandwidth();
1862
                                $cflink['bandwidthtype'] = $this->GetBwscale();
1863
                                $cflink['enabled'] = $this->GetEnabled();
1864
                                $cflink['default'] = $this->GetDefault();
1865
                                $cflink['red'] = $this->GetRed();
1866
                                $cflink['rio'] = $this->GetRio();
1867
                                $cflink['ecn'] = $this->GetEcn();
1868
                                $cflink['borrow'] = $this->GetBorrow();
1869
                		if (is_array($this->queues)) {
1870
 		                       $cflinkp['queue'] = array();
1871
                        		foreach ($this->subqueues as $q) {
1872
 		                                $cflink['queue'][$q->GetQname()] = array();
1873
                		                $q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
1874
					}
1875
                		}
1876

    
1877
		}
1878
	
1879
		/*
1880
		 * Should search even its childs
1881
		 */
1882
		function &find_queue($interface, $qname) {
1883
				if ($qname == $this->GetQname())
1884
						return $this;
1885
				foreach ($this->subqueues as $q) {
1886
						$result =& $q->find_queue("", $qname);
1887
			if ($result)
1888
								return $result;
1889
				}
1890
		}
1891

    
1892
	function &find_parentqueue($interface, $qname) {
1893
				if ($this->subqueues[$qname])
1894
						return $this;
1895
				foreach ($this->subqueues as $q) {
1896
					$result = $q->find_parentqueue("", $qname);
1897
			if ($result)
1898
				return $result;
1899
		}
1900
		}
1901

    
1902
		function delete_queue() {
1903
			unref_on_altq_queue_list($this->GetQname());
1904
			if ($this->GetDefault())
1905
				altq_set_default_queue($this->GetInterface(), "false");
1906
			cleanup_queue_from_rules($this->GetQname());
1907
			foreach ($this->subqueues as $q) {
1908
			$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
1909
				$q->delete_queue();
1910
			}
1911
			unset_object_by_reference($this->GetLink());
1912
		}
1913
	
1914
	function validate_input($data, &$input_errors) {
1915
		parent::validate_input($data, $input_errors);
1916
		
1917
		if ($data['priority'] > 7)
1918
				$input_errors[] = "Priority must be an integer between 1 and 7.";
1919
		$reqfields[] = "bandwidth";
1920
		$reqdfieldsn[] = "Bandwidth";
1921
		$reqfields[] = "bandwidthtype";
1922
		$reqdfieldsn[] = "Bandwidthtype";
1923

    
1924
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
1925
		
1926
		if ($data['bandwidth'] && !is_numeric($data['bandwidth']))
1927
                 $input_errors[] = "Bandwidth must be an integer.";
1928

    
1929

    
1930
           if ($data['bandwidth'] < 0)
1931
                       $input_errors[] = "Bandwidth cannot be negative.";
1932

    
1933

    
1934
           if ($data['bandwidthtype'] == "%") {
1935
                 if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
1936
                       $input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
1937
           }
1938

    
1939
/*
1940
           $parent =& $this->GetParent();
1941
           switch ($data['bandwidthtype']) {
1942
                       case "%":
1943
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
1944
                       default:
1945
                             $mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
1946
                             break;
1947
           }
1948
                if ($parent->GetAvailableBandwidth() < floatval($myBw))
1949
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
1950
*/
1951
	}
1952
		function ReadConfig(&$q) {
1953
				parent::ReadConfig($q);
1954
		if ($q['borrow'])
1955
			$this->SetBorrow("on");
1956
		}
1957
		
1958
	function build_javascript() {
1959
		return parent::build_javascript();
1960
	}
1961

    
1962
	function build_tree() {
1963
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface()."&queue=" . $this->GetQname()."&action=show"; 
1964
			$tree .= "\" ";
1965
			if ($this->GetDefault())
1966
								$tree .= " class=\"navlnk\"";
1967
			$tree .= " >" . $this->GetQname() . "</a>";
1968
			if (is_array($this->subqueues)) {
1969
				$tree .= "<ul>";
1970
				foreach ($this->subqueues as $q)  {
1971
					$tree .= $q->build_tree();
1972
				}	
1973
				$tree .= "</ul>";
1974
			}
1975
			$tree .= "</li>";
1976
			return $tree;
1977
	}
1978
		
1979
	/* Even this should take childs in consideration */
1980
	function build_rules() {
1981
		   $pfq_rule = "queue ". $this->qname;
1982
			if ($this->GetInterface())
1983
					$pfq_rule .= " on ".convert_friendly_interface_to_real_interface_name($this->GetInterface());
1984
			if ($this->GetBandwidth() && $this->GetBwscale())
1985
					$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
1986
			if ($this->GetQpriority())
1987
					$pfq_rule .= " priority " . $this->GetQpriority();
1988
			if ($this->GetQlimit())
1989
					$pfq_rule .= " qlimit " . $this->GetQlimit();
1990
			if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetBorrow()) {
1991
				$pfq_rule .= " cbq ( ";
1992
				if ($this->GetRed()) {
1993
						$comma = 1;
1994
						$pfq_rule .= " red ";
1995
				}
1996
				if ($this->GetRio()) {
1997
						if ($comma) 
1998
								$pfq_rule .= " ,";
1999
						$comma = 1;
2000
						$pfq_rule .= " rio ";
2001
				}
2002
				if ($this->GetEcn()) {
2003
						if ($comma) 
2004
								$pfq_rule .= " ,";
2005
						$comma = 1;
2006
						$pfq_rule .= " ecn ";
2007
				}
2008
				if ($this->GetDefault()) {
2009
						if ($comma)
2010
								$pfq_rule .= " ,";
2011
						$comma = 1;
2012
						$pfq_rule .= " default ";
2013
				}
2014
				if ($this->GetBorrow()) {
2015
					if ($comma)
2016
						$pfq_rule .= ", ";
2017
					$pfq_rule .= " borrow ";
2018
				}
2019
				$pfq_rule .= " ) ";
2020
			} 
2021
			if (count($this->subqueues)) {
2022
					$i = count($this->subqueues);
2023
					$pfq_rule .= " { ";
2024
					foreach ($this->subqueues as $qkey => $qnone) {
2025
							if ($i > 1) {
2026
									$i--;
2027
									$pfq_rule .= " {$qkey}, ";
2028
							} else
2029
									$pfq_rule .= " {$qkey} ";
2030
					}
2031
					$pfq_rule .= " } \n";
2032
					foreach ($this->subqueues as $q)
2033
							$pfq_rule .= $q->build_rules();
2034
			}
2035

    
2036
			$pfq_rule .= " \n";
2037
			return $pfq_rule;
2038
	}
2039

    
2040
	function build_form() {
2041
		$form = "<tr>";
2042
		$form .= "<td valign=\"top\" class=\"vncellreq\">Bandwidth</td>";
2043
		$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
2044
		if ($this->GetBandwidth() > 0)
2045
				$form .= htmlspecialchars($this->GetBandwidth());
2046
		$form .= "\">";
2047
		$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
2048
		$form .= "<option value=\"Gb\"";
2049
		if ($this->GetBwscale() == "Gb")
2050
				$form .= " selected=\"yes\"";
2051
		$form .= ">Gbit/s</option>";
2052
		$form .= "<option value=\"Mb\"";
2053
		if ($this->GetBwscale() == "Mb")
2054
				$form .= " selected=\"yes\"";
2055
		$form .= ">Mbit/s</option>";
2056
		$form .= "<option value=\"Kb\"";
2057
		if ($this->GetBwscale() == "Kb")
2058
				$form .= " selected=\"yes\"";
2059
		$form .= ">Kbit/s</option>";
2060
		$form .= "<option value=\"\"";
2061
		if ($this->GetBwscale() == "b")
2062
				$form .= " selected=\"yes\"";
2063
		$form .= ">Bit/s</option>";
2064
		$form .= "<option value=\"%\"";
2065
		if ($this->GetBwscale() == "%")
2066
				$form .= " selected=\"yes\"";
2067
		$form .= ">%</option>";
2068
		$form .= "</select> <br>";
2069
		$form .= "<span class=\"vexpl\">Choose the amount of bandwidth for this queue";
2070
		$form .= "</span></td></tr>";
2071
		$form .= parent::build_form();
2072
		$form .= "<tr><td class=\"vncellreq\">Scheduler specific options</td>";
2073
		$form .= "<td class=\"vtable\"><input type=\"checkbox\" id=\"borrow\" name=\"borrow\"";
2074
			if($this->GetBorrow() == "on") 
2075
		$form .=  " CHECKED ";
2076
		$form .= "> Borrow from other queues when available<br></td></tr>";
2077

    
2078
		return $form;
2079
	}
2080

    
2081
	function update_altq_queue_data(&$data) { 
2082
		$this->ReadConfig($data);
2083
	}
2084

    
2085
	function wconfig() {
2086
		$cflink =& get_reference_to_me_in_config($this->GetLink());
2087
				if (!is_array($cflink))
2088
						$cflink = array();
2089
				$cflink['interface'] = $this->GetInterface();
2090
				$cflink['qlimit'] = $this->GetQlimit();
2091
				$cflink['priority'] = $this->GetQpriority();
2092
				$cflink['name'] = $this->GetQname();
2093
				$cflink['description'] = $this->GetDescription();
2094
				$cflink['bandwidth'] = $this->GetBandwidth();
2095
				$cflink['bandwidthtype'] = $this->GetBwscale();
2096
				$cflink['enabled'] = $this->GetEnabled();
2097
				$cflink['default'] = $this->GetDefault();
2098
				$cflink['red'] = $this->GetRed();
2099
				$cflink['rio'] = $this->GetRio();
2100
				$cflink['ecn'] = $this->GetEcn();
2101
				$cflink['borrow'] = $this->GetBorrow();
2102
		}
2103
}
2104

    
2105
class fairq_queue extends priq_queue {
2106
		var $hogs;
2107
		var $buckets;
2108

    
2109
	function GetBuckets() {
2110
		return $this->buckets;
2111
	}
2112
	function SetBuckets($buckets) {
2113
		$this->buckets = $buckets;
2114
	}
2115
	function GetHogs() {
2116
		return $this->hogs;
2117
	}
2118
	function SetHogs($hogs) {
2119
		$this->hogs = $hogs;
2120
	}
2121
	function CanHaveChilds() {
2122
		return false;
2123
	}
2124

    
2125

    
2126
	function copy_queue($interface, &$cflink) {
2127
                $cflink['interface'] = $interface;
2128
                $cflink['qlimit'] = $this->GetQlimit();
2129
                $cflink['priority'] = $this->GetQpriority();
2130
                $cflink['name'] = $this->GetQname();
2131
                $cflink['description'] = $this->GetDescription();
2132
                $cflink['bandwidth'] = $this->GetBandwidth();
2133
                $cflink['bandwidthtype'] = $this->GetBwscale();
2134
                $cflink['enabled'] = $this->GetEnabled();
2135
                $cflink['default'] = $this->GetDefault();
2136
                $cflink['red'] = $this->GetRed();
2137
                $cflink['rio'] = $this->GetRio();
2138
                $cflink['ecn'] = $this->GetEcn();
2139
                $cflink['buckets'] = $this->GetBuckets();
2140
		$cflink['hogs'] = $this->GetHogs();
2141
	}
2142
	
2143
	/*
2144
	 * Should search even its childs
2145
	 */
2146
	function &find_queue($interface, $qname) {
2147
		if ($qname == $this->GetQname())
2148
			return $this;
2149
	}
2150

    
2151
	function find_parentqueue($interface, $qname) { return; }
2152

    
2153
	function delete_queue() {
2154
		unref_on_altq_queue_list($this->GetQname());
2155
		if ($this->GetDefault())
2156
			altq_set_default_queue($this->GetInterface(), "false");
2157
		cleanup_queue_from_rules($this->GetQname());
2158
		unset_object_by_reference($this->GetLink());
2159
	}
2160
	
2161
	function validate_input($data, &$input_errors) {
2162
		parent::validate_input($data, $input_errors);
2163
		
2164
		if ($data['priority'] > 255)
2165
				$input_errors[] = "Priority must be an integer between 1 and 255.";
2166
		$reqfields[] = "bandwidth";
2167
		$reqdfieldsn[] = "Bandwidth";
2168
		$reqfields[] = "bandwidthtype";
2169
		$reqdfieldsn[] = "Bandwidthtype";
2170

    
2171
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
2172
		
2173
		if ($data['bandwidth'] && !is_numeric($data['bandwidth']))
2174
	                 $input_errors[] = "Bandwidth must be an integer.";
2175

    
2176

    
2177
	        if ($data['bandwidth'] < 0)
2178
                       $input_errors[] = "Bandwidth cannot be negative.";
2179

    
2180

    
2181
        	if ($data['bandwidthtype'] == "%") {
2182
                	if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
2183
                       		$input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
2184
           	}
2185

    
2186
/*
2187
           	$parent =& $this->GetParent();
2188
           	switch ($data['bandwidthtype']) {
2189
                       case "%":
2190
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
2191
                       default:
2192
                             $mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
2193
                             break;
2194
           	}
2195
                if ($parent->GetAvailableBandwidth() < floatval($myBw))
2196
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
2197
*/
2198
	}
2199
	
2200
	function ReadConfig(&$q) {
2201
		parent::ReadConfig($q);
2202
		if ($q['buckets'])
2203
			$this->SetBuckets($q['buckets']);
2204
		if ($q['hogs'] && is_valid_shaperbw($q['hogs']))
2205
			$this->SetHogs($q['hogs']);
2206
	}
2207
		
2208
	function build_javascript() {
2209
		return parent::build_javascript();
2210
	}
2211

    
2212
	function build_tree() {
2213
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . 
2214
			$this->GetInterface()."&queue=" . $this->GetQname()."&action=show"; 
2215
			$tree .= "\" ";
2216
			if ($this->GetDefault())
2217
				$tree .= " class=\"navlnk\"";
2218
			$tree .= " >" . $this->GetQname() . "</a>";
2219
			$tree .= "</li>";
2220
			return $tree;
2221
	}
2222
		
2223
	/* Even this should take childs in consideration */
2224
	function build_rules() {
2225
		$pfq_rule = "queue ". $this->qname;
2226
		if ($this->GetInterface())
2227
			$pfq_rule .= " on ".convert_friendly_interface_to_real_interface_name($this->GetInterface());
2228
		if ($this->GetBandwidth() && $this->GetBwscale())
2229
			$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
2230
		if ($this->GetQpriority())
2231
			$pfq_rule .= " priority " . $this->GetQpriority();
2232
		if ($this->GetQlimit())
2233
			$pfq_rule .= " qlimit " . $this->GetQlimit();
2234
		if ($this->GetDefault() || $this->GetRed() || $this->GetRio() 
2235
			|| $this->GetEcn() || $this->GetBuckets() || $this->GetHogs()) {
2236
			$pfq_rule .= " fairq ( ";
2237
			if ($this->GetRed()) {
2238
				$comma = 1;
2239
				$pfq_rule .= " red ";
2240
			}
2241
			if ($this->GetRio()) {
2242
				if ($comma) 
2243
					$pfq_rule .= " ,";
2244
				$comma = 1;
2245
				$pfq_rule .= " rio ";
2246
			}
2247
			if ($this->GetEcn()) {
2248
				if ($comma) 
2249
					$pfq_rule .= " ,";
2250
				$comma = 1;
2251
				$pfq_rule .= " ecn ";
2252
			}
2253
			if ($this->GetDefault()) {
2254
				if ($comma)
2255
					$pfq_rule .= " ,";
2256
				$comma = 1;
2257
				$pfq_rule .= " default ";
2258
			}
2259
			if ($this->GetBuckets()) {
2260
				if ($comma)
2261
					$pfq_rule .= ", ";
2262
				$pfq_rule .= " buckets " . $this->GetBuckets() . " ";
2263
			}
2264
			if ($this->GetHogs()) {
2265
				if ($comma)
2266
					$pfq_rule .= ", ";
2267
				$pfq_rule .= " hogs " . $this->GetHogs() . " ";
2268
			}
2269
				$pfq_rule .= " ) ";
2270
		} 
2271

    
2272
		$pfq_rule .= " \n";
2273
		return $pfq_rule;
2274
	}
2275

    
2276
	function build_form() {
2277
		$form = "<tr>";
2278
		$form .= "<td valign=\"top\" class=\"vncellreq\">Bandwidth</td>";
2279
		$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
2280
		if ($this->GetBandwidth() > 0)
2281
				$form .= htmlspecialchars($this->GetBandwidth());
2282
		$form .= "\">";
2283
		$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
2284
		$form .= "<option value=\"Gb\"";
2285
		if ($this->GetBwscale() == "Gb")
2286
				$form .= " selected=\"yes\"";
2287
		$form .= ">Gbit/s</option>";
2288
		$form .= "<option value=\"Mb\"";
2289
		if ($this->GetBwscale() == "Mb")
2290
				$form .= " selected=\"yes\"";
2291
		$form .= ">Mbit/s</option>";
2292
		$form .= "<option value=\"Kb\"";
2293
		if ($this->GetBwscale() == "Kb")
2294
				$form .= " selected=\"yes\"";
2295
		$form .= ">Kbit/s</option>";
2296
		$form .= "<option value=\"\"";
2297
		if ($this->GetBwscale() == "b")
2298
				$form .= " selected=\"yes\"";
2299
		$form .= ">Bit/s</option>";
2300
		$form .= "<option value=\"%\"";
2301
		if ($this->GetBwscale() == "%")
2302
				$form .= " selected=\"yes\"";
2303
		$form .= ">%</option>";
2304
		$form .= "</select> <br>";
2305
		$form .= "<span class=\"vexpl\">Choose the amount of bandwidth for this queue";
2306
		$form .= "</span></td></tr>";
2307
		$form .= parent::build_form();
2308
		$form .= "<tr><td class=\"vncellreq\">Scheduler specific options</td>";
2309
		$form .= "<td class=\"vtable\"><table><tr><td>";
2310
		$form .= "<input id=\"buckets\" name=\"buckets\" value=\"";
2311
			if($this->GetBuckets()) 
2312
				$form .=  $this->GetBuckets();
2313
		$form .= "\"> Number of buckets available.<br></td></tr>";
2314
		$form .= "<tr><td class=\"vtable\"><input id=\"hogs\" name=\"hogs\" value=\"";
2315
			if($this->GetHogs()) 
2316
				$form .=  $this->GetHogs();
2317
		$form .= "\"> Bandwidth limit for hosts to not saturate link.<br></td></tr>";
2318
		$form .= "</table></td></tr>";
2319
		return $form;
2320
	}
2321

    
2322
	function update_altq_queue_data(&$data) { 
2323
		$this->ReadConfig($data);
2324
	}
2325

    
2326
	function wconfig() {
2327
		$cflink =& get_reference_to_me_in_config($this->GetLink());
2328
		if (!is_array($cflink))
2329
			$cflink = array();
2330
		$cflink['interface'] = $this->GetInterface();
2331
		$cflink['qlimit'] = $this->GetQlimit();
2332
		$cflink['priority'] = $this->GetQpriority();
2333
		$cflink['name'] = $this->GetQname();
2334
		$cflink['description'] = $this->GetDescription();
2335
		$cflink['bandwidth'] = $this->GetBandwidth();
2336
		$cflink['bandwidthtype'] = $this->GetBwscale();
2337
		$cflink['enabled'] = $this->GetEnabled();
2338
		$cflink['default'] = $this->GetDefault();
2339
		$cflink['red'] = $this->GetRed();
2340
		$cflink['rio'] = $this->GetRio();
2341
		$cflink['ecn'] = $this->GetEcn();
2342
		$cflink['buckets'] = $this->GetBuckets();
2343
		$cflink['hogs'] = $this->GetHogs();
2344
	}
2345
}
2346

    
2347

    
2348

    
2349
/*
2350
 * XXX: TODO Make a class shaper to hide all these function
2351
 * from the global namespace.
2352
 */
2353

    
2354
/* 
2355
 * This is a layer violation but for now there is no way 
2356
 * i can find to properly do this with PHP.
2357
 */
2358
function altq_set_default_queue($interface, $value) {
2359
	global $altq_list_queues;
2360
		
2361
	$altq_tmp =& $altq_list_queues[$interface];
2362
	if ($altq_tmp) {
2363
		if ($value) {
2364
			$altq_tmp->SetDefaultQueuePresent("true");
2365
		}
2366
		else {
2367
			$altq_tmp->SetDefaultQueuePresent("false");
2368
		}
2369
	}
2370
}
2371

    
2372
function altq_get_default_queue($interface) {
2373
	global $altq_list_queues;
2374

    
2375
	$altq_tmp = $altq_list_queues[$interface];
2376
	if ($altq_tmp)  
2377
		return $altq_tmp->GetDefaultQueuePresent(); 
2378
}
2379

    
2380
function altq_check_default_queues() {
2381
	global $altq_list_queues;
2382

    
2383
	$count = 0;
2384
	if (is_array($altq_list_queues)) {
2385
		foreach($altq_list_queues as $altq) {
2386
			if ($altq->GetDefaultQueuePresent())
2387
				$count++;
2388
		}
2389
	}
2390
	else  $count++;;
2391
	
2392
	return 0;
2393
}
2394

    
2395
function &get_unique_queue_list() {
2396
	global $altq_list_queues;
2397
	
2398
	$qlist = array();
2399
	if (is_array($altq_list_queues)) {
2400
		foreach ($altq_list_queues as $altq) {
2401
			$tmplist =& $altq->get_queue_list();
2402
			foreach ($tmplist as $qname => $link)
2403
				$qlist[$qname] = $link;	
2404
		}
2405
	}
2406
	return $qlist;
2407
}
2408

    
2409
function get_is_ftp_queue($interface, $qname) {
2410
	global $config;
2411

    
2412
	if (isset($config['interfaces'][$interface]['ftpqueue']) &&
2413
		$config['interfaces'][$interface]['ftpqueue'] == $qname)
2414
		return true;
2415
	return false;
2416
}
2417

    
2418
function set_is_ftp_queue($interface, $qname) {
2419
	global $config;
2420

    
2421
	if (!is_array($config['interfaces'][$interface]['ftpqueue']))
2422
		$config['interfaces'][$interface]['ftpqueue'] = array();
2423
	$config['interfaces'][$interface]['ftpqueue'] = $qname;
2424
}
2425

    
2426
function ref_on_altq_queue_list($parent, $qname) {
2427
	if (isset($GLOBALS['queue_list'][$qname]))
2428
		$GLOBALS['queue_list'][$qname]++;
2429
	else
2430
		$GLOBALS['queue_list'][$qname] = 1;
2431

    
2432
	unref_on_altq_queue_list($parent);
2433
}
2434

    
2435
function unref_on_altq_queue_list($qname) {
2436
	$GLOBALS['queue_list'][$qname]--;
2437
	if ($GLOBALS['queue_list'][$qname] <= 1)
2438
		unset($GLOBALS['queue_list'][$qname]);	
2439
}
2440

    
2441
function read_altq_config() {
2442
	global $altq_list_queues, $config;
2443
	$path = array();
2444
	
2445
	$a_int = &$config['shaper']['queue'];
2446

    
2447
	$altq_list_queues = array();
2448
	
2449
	if (!is_array($config['shaper']['queue']))
2450
		return;
2451

    
2452
	foreach ($a_int as $key => $conf) {
2453
				$int = $conf['interface'];
2454
				$root =& new altq_root_queue();
2455
				$root->SetInterface($int);
2456
				$altq_list_queues[$root->GetInterface()] = &$root;
2457
				$root->ReadConfig($conf);
2458
		array_push($path, $key);
2459
		$root->SetLink($path);
2460
		if (is_array($conf['queue'])) {
2461
			foreach ($conf['queue'] as $key1 => $q) {
2462
				array_push($path, $key1);
2463
				/* 
2464
				 * XXX: we compeletely ignore errors here but anyway we must have 
2465
				 *	checked them before so no harm should be come from this.
2466
				 */
2467
				$root->add_queue($root->GetInterface(), $q, &$path, $input_errors);
2468
				array_pop($path);
2469
			} 	
2470
				}
2471
		array_pop($path);
2472
	}
2473
}
2474

    
2475

    
2476

    
2477
function get_interface_list_to_show() {
2478
	global $altq_list_queues, $config;
2479
		
2480
	$tree = "";
2481
	foreach ($config['interfaces'] as $if => $ifdesc) {
2482
		if ($altq_list_queues[$if]) {
2483
			continue;
2484
		} else  {
2485
			if (!is_altq_capable($ifdesc['if']))
2486
				continue;
2487
			if (!isset($ifdesc['enable']) && $if != "lan" && $if != "wan") 
2488
				continue;
2489
			$tree .= " <li><a href=\"firewall_shaper.php?interface=".$if."&action=add\">".$if."</a></li>";
2490
		}
2491
	}
2492
	
2493
	return $tree;
2494
}
2495

    
2496
function filter_generate_altq_queues() {
2497
	global $altq_list_queues;
2498
	
2499
	read_altq_config();
2500

    
2501
	$altq_rules = "";
2502
	foreach ($altq_list_queues as $altq) 
2503
		$altq_rules .= $altq->build_rules();
2504

    
2505
	return $altq_rules;
2506
}
2507

    
2508

    
2509
function build_iface_without_this_queue($iface, $qname) {
2510
	global $g, $altq_list_queues;
2511

    
2512
	$altq =& $altq_list_queues[$iface];
2513
				if ($altq)
2514
						$scheduler = ": " . $altq->GetScheduler();
2515
	$form = "<tr><td width=\"20%\" >";
2516
	$form .= "<a href=\"firewall_shaper.php?interface" . $iface . "&queue=" . $iface."&action=show\">".$iface.": ".$scheduler."</a>";
2517
		$form .= "</td></tr>";
2518
		$form .= "<tr><td width=\"100%\" class=\"vncellreq\">";
2519
		$form .= "<a href=\"firewall_shaper_queues.php?interface=";
2520
		$form .= $iface . "&queue=". $qname . "&action=add\">";
2521
		$form .= "<img src=\"";
2522
		$form .= "./themes/".$g['theme']."/images/icons/icon_plus.gif\"";
2523
		$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Clone shaper/queue on this interface\">";
2524
		$form .= " Clone shaper/queue on this interface</a></td></tr>";
2525

    
2526
		return $form;
2527

    
2528
}
2529

    
2530

    
2531
$default_shaper_msg =	"<tr><td align=\"center\" width=\"80%\" >";
2532
$default_shaper_msg .= "<span class=\"vexpl\"><strong><p><b>Welcome to the pfSense Traffic Shaper.</b><br />";
2533
$default_shaper_msg .= "The tree on the left helps you navigate through the queues <br />";
2534
$default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
2535
$default_shaper_ms .= " </p></strong></span>";
2536
$default_shaper_msg .= "</td></tr>";
2537

    
2538
?>
(20-20/29)