Project

General

Profile

Download (76.1 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
		/* Nothing to do */
63
		break;
64
	case 'PRIQ':
65
		if (isset($ref['borrow'])) unset($ref['borrow']);		
66
		if (isset($ref['bandwidth'])) unset($ref['bandwidth']);
67
		if (isset($ref['bandwidthtype'])) unset($ref['bandwidthtype']);
68
		/* fall through */
69
	case 'CBQ':
70
		if (isset($ref['realtime'])) unset($ref['realtime']);	
71
		if (isset($ref['realtime1'])) unset($ref['realtime1']);
72
		if (isset($ref['realtime2'])) unset($ref['realtime2']);
73
		if (isset($ref['realtime3'])) unset($ref['realtime3']);
74
		if (isset($ref['upperlimit'])) unset($ref['upperlimit']);
75
				if (isset($ref['upperlimit1'])) unset($ref['upperlimit1']);
76
				if (isset($ref['upperlimit2'])) unset($ref['upperlimit2']);
77
				if (isset($ref['upperlimit3'])) unset($ref['upperlimit3']);
78
		if (isset($ref['linkshare'])) unset($ref['linkshare']);
79
				if (isset($ref['linkshare1'])) unset($ref['linkshare1']);
80
				if (isset($ref['linkshare2'])) unset($ref['linkshare2']);
81
				if (isset($ref['linkshare3'])) unset($ref['linkshare3']);	
82
		break;
83
	}
84
}
85

    
86
function get_bandwidthtype_scale($type) {
87
        switch ($type) {
88
        case "Gb":
89
                $factor = 1000 * 1000 * 1000;
90
        break;
91
        case "Mb":
92
                $factor = 1000 * 1000;
93
        break;
94
        case "Kb":
95
                $factor = 1000;
96
        break;
97
        case "b":
98
        default:
99
                $factor = 1;
100
        break;
101
        }
102
        return floatval($factor);
103
}
104

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

    
126
function get_interface_bandwidth($object) {
127
	global $altq_list_queues;
128

    
129
        $int = $object->GetInterface();
130
        $altq =& $altq_list_queues[$int];
131
        if ($altq) {
132
                $bw_3 = $altq->GetBandwidth();
133
                $bw_3 = $bw_3 *  get_bandwidthtype_scale($altq->GetBwscale());
134
		return floatval($bw_3);
135
        } else return 0;
136
}
137

    
138
/*
139
 * This is duplicated here since we cannot include guiconfig.inc.
140
 * Including it makes all stuff break.
141
 */
142
function shaper_do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors) {
143

    
144
        /* check for bad control characters */
145
        foreach ($postdata as $pn => $pd) {
146
                if (is_string($pd) && preg_match("/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/", $pd)) {
147
                        $input_errors[] = "The field '" . $pn . "' contains invalid characters.";
148
                }
149
        }
150

    
151
        for ($i = 0; $i < count($reqdfields); $i++) {
152
                if ($postdata[$reqdfields[$i]] == "") {
153
                        $input_errors[] = "The field '" . $reqdfieldsn[$i] . "' is required.";
154
                }
155
        }
156
}
157

    
158
function cleanup_queue_from_rules($queue) {
159
	global $config;
160

    
161
	foreach ($config['filter']['rule'] as $rule) {
162
		if ($rule['defaultqueue'] == $queue)
163
			unset($rule['defaultqueue']);
164
		if ($rule['ackqueue'] == $queue)
165
			unset($rule['ackqueue']);
166
	}
167
	foreach ($config['interfaces'] as $if => $ifdata) {
168
			if ($ifdata['ftpqueue'] == $queue) {
169
				unset($config['interfaces'][$if]['ftpqueue']);
170
				break;
171
			}
172
	}
173
}
174

    
175
class altq_root_queue {
176
		var $interface;
177
		var $tbrconfig ;
178
		var $bandwidth;
179
		var $bandwidthtype; /* b, Kb, Mb */
180
		var $scheduler;
181
		var $qlimit;
182
		var $queues = array();
183
		var $qenabled;
184
		var $link;
185
		var $default_present; /* if we have a default queue set */
186
		var $available_bw; /* in b/s */
187

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

    
285

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

    
311
	}
312
	
313
	function copy_queue($interface, &$cflink) {
314
                $cflink['interface'] = $interface;
315
                $cflink['name'] = $interface;
316
                $cflink['scheduler'] = $this->GetScheduler();
317
                $cflink['bandwidth'] = $this->GetBandwidth();
318
                $cflink['bandwidthtype'] = $this->GetBwscale();
319
                $cflink['qlimit'] = $this->GetQlimit();
320
                $cflink['tbrconfig'] = $this->GetTbrConfig();
321
                $cflink['enabled'] = $this->GetEnabled();
322
		if (is_array($this->queues)) {
323
			$cflink['queue'] = array();
324
			foreach ($this->queues as $q) {
325
				$cflink['queue'][$q->GetQname()] = array();
326
				$q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
327
			}
328
		}
329
	}
330

    
331

    
332
		function &get_queue_list($q = null) {
333
			$qlist = array();
334

    
335
			$qlist[$this->GetQname()] = & $this;
336
			if (is_array($this->queues)) {
337
				foreach ($this->queues as $queue)
338
					$queue->get_queue_list(&$qlist);
339
			}
340
			return $qlist;
341
		}
342

    
343
		function &add_queue($interface, &$queue, &$path, &$input_errors) {
344

    
345
			if (!is_array($this->queues))
346
				$this->queues = array();
347
				
348
			switch ($this->GetScheduler()) {
349
				case "PRIQ":
350
					$q =& new priq_queue();
351
					break;
352
				case "HFSC":
353
					$q =& new hfsc_queue();
354
					break;
355
				case "CBQ":
356
						$q =& new cbq_queue();
357
					break;
358
				default:
359
					/* XXX: but should not happen anyway */ 
360
					return;
361
					break;
362
			}
363
			$q->SetLink($path);
364
			$q->SetInterface($this->GetInterface());
365
			$q->SetEnabled("on");
366
			$q->SetParent(&$this);
367
			$q->ReadConfig($queue);
368
			$q->validate_input($queue, $input_errors);
369
                 if (count($input_errors)) {
370
                       return $q;
371
                 }
372

    
373
                 if (isset($queue['bandwidth'])) {
374
                         switch ($queue['bandwidthtype']) {
375
                         case "%":
376
                                $myBw = $this->GetAvailableBandwidth() * $queue['bandwidth'] / 100;
377
                                break;
378
                        default:
379
                                $myBw = $queue['bandwidth'] * get_bandwidthtype_scale($queue['bandwdithtype']);
380
                                break;
381
                        }
382
                 	}
383
			$q->SetAvailableBandwidth($myBw);
384
                        $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
385
			$this->queues[$q->GetQname()] = &$q; 
386
			ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
387
			if (is_array($queue['queue'])) {
388
				foreach ($queue['queue'] as $key1 => $que) {
389
					array_push($path, $key1);
390
								$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
391
					array_pop($path);
392
						}
393
			}
394
	
395
			return $q;
396
		}
397

    
398
		/* interface here might be optional */
399
		function &find_queue($interface, $qname) {
400
			if ($qname == $this->GetQname()) {
401
				return $this;
402
			} 
403
			foreach ($this->queues as $q) {
404
				$result =& $q->find_queue("", $qname);
405
				if ($result)
406
					return $result;
407
			}
408
		}
409

    
410
	function &find_parentqueue($interface, $qname) {
411
		if ($qname == $interface) {
412
			$result =  NULL;
413
		} else if ($this->queues[$qname])	 {
414
			$result = $this;
415
		} else if ($this->GetScheduler() <> "PRIQ") {
416
			foreach ($this->queues as $q) {
417
				$result = $q->find_parentqueue("", $qname);
418
				if ($result)
419
					return $result;
420
			}
421
		}
422
	}
423

    
424
	function build_tree() {
425
		$tree = " <li><a href=\"firewall_shaper.php?interface=".$this->GetInterface()."&queue=". $this->GetInterface()."&action=show"; 
426
		$tree .= "\">" . $this->GetInterface() . "</a>";
427
		if (is_array($this->queues)) {
428
			$tree .= "<ul>";
429
			foreach ($this->queues as $q)  {
430
				$tree .= $q->build_tree();
431
			}
432
		$tree .= "</ul>";
433
		}
434
		$tree .= "</li>";
435
		return $tree;
436
	}
437
	
438
	function delete_queue() { 
439
		foreach ($this->queues as $q) {
440
		$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
441
			$q->delete_queue();			
442
		}
443
		unset_object_by_reference($this->GetLink());
444
	 }
445

    
446
	function delete_all() {
447
                if (count($this->queues)) {
448
                        foreach ($this->queues as $q) {
449
                        	$q->delete_all();
450
                        	unset_object_by_reference($q->GetLink());
451
                                unset($q);
452
               		}
453
        	        unset($this->queues);
454
                }
455
        }
456

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

    
495
	function build_javascript() {
496
			$javascript = "<script type=\"text/javascript\">";
497
			$javascript .= "function mySuspend() {";
498
			$javascript .= "if (document.layers && document.layers['shaperarea'] != null);";
499
			$javascript .= "document.layers['shaperarea'].visibility = 'hidden';";
500
			$javascript .= "else if (document.all)";
501
			$javascript .= "document.all['shaperarea'].style.visibility = 'hidden';";
502
			$javascript .= "}";
503

    
504
			$javascript .= "function myResume() {";
505
			$javascript .= "if (document.layers && document.layers['shaperarea'] != null)";
506
			$javascript .= "document.layers['shaperarea'].visibility = 'visible';";
507
			$javascript .= "else if (document.all)";
508
			$javascript .= "document.all['shaperarea'].style.visibility = 'visible';";
509
			$javascript .= "}";
510
			$javascript .= "</script>";
511

    
512
			return $javascript;
513
	}
514
	
515
	function build_shortform() {
516
			global $g;
517

    
518
			$altq =& $this;
519
			if ($altq)
520
					$scheduler = ": " . $altq->GetScheduler();
521
			$form = "<tr><td width=\"20%\" class=\"vtable\">";
522
			$form .= "<a href=\"firewall_shaper.php?interface" . $this->GetInterface() . "&queue=". $this->GetInterface()."&action=show\">".$this->GetInterface().": ".$scheduler."</a>";
523
			$form .= "</td></tr>";
524
			$form .= "<tr>";
525
			$form .= "<td width=\"50%\" class=\"vncellreq\">";
526
			$form .= "Bandwidth: " . $this->GetBandwidth().$this->GetBwscale();
527
			$form .= "</td><td width=\"50%\"></td></tr>";
528
			$form .= "<tr><td width=\"20%\" class=\"vncellreq\">";
529
			$form .= "<a href=\"firewall_shaper_queues.php?interface=";
530
			$form .= $this->GetInterface() . "&queue=";
531
			$form .= $this->GetQname() . "&action=delete\">";
532
			$form .= "<img src=\"";
533
			$form .= "./themes/".$g['theme']."/images/icons/icon_x.gif\"";
534
			$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Disable shaper on i
535
nterface\">";
536
			$form .= "<span>Disable shaper on interface</span></a></td></tr>";
537

    
538
			return $form;
539

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

    
615

    
616
		return $form;
617
	}
618

    
619
		function update_altq_queue_data(&$data) { 
620
		$this->ReadConfig($data);
621
	}
622
	
623
	/*
624
	 * Should call on each of it queues and subqueues
625
	 * the same function much like build_rules();
626
	 */
627
	function wconfig() { 
628
		$cflink = &get_reference_to_me_in_config($this->GetLink());
629
		if (!is_array($cflink))
630
			$cflink = array();
631
		$cflink['interface'] = $this->GetInterface();	
632
		$cflink['name'] = $this->GetQname();
633
		$cflink['scheduler'] = $this->GetScheduler();
634
		$cflink['bandwidth'] = $this->GetBandwidth();
635
		$cflink['bandwidthtype'] = $this->GetBwscale();
636
		$cflink['qlimit'] = $this->GetQlimit();
637
		$cflink['tbrconfig'] = $this->GetTbrConfig();
638
		$cflink['enabled'] = $this->GetEnabled();
639
	}
640

    
641
}
642

    
643
class priq_queue {
644
	var $qname;
645
	var $qinterface; 
646
	var $qlimit;
647
	var $qpriority;
648
	var $description;
649
	var $isparent;
650
	var $qbandwidth;
651
	var $qbandwidthtype;
652
	var $qdefault;
653
	var $qrio;
654
	var $qred;
655
	var $qecn;
656
	var $qack;
657
	var $qenabled;
658
	var $qparent;
659
	var $link;
660
	var $available_bw; /* in b/s */
661

    
662
	/* This is here to help on form building and building rules/lists */
663
		var $subqueues = array();
664

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

    
776
	function build_javascript() {
777
		$javascript = "<script type=\"text/javascript\">";
778
		$javascript .= "function mySuspend() { \n";
779
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null);\n";
780
		$javascript .= "document.layers['shaperarea'].visibility = 'hidden';\n";
781
		$javascript .= "else if (document.all)\n";
782
		$javascript .= "document.all['shaperarea'].style.visibility = 'hidden';\n";
783
		$javascript .= "}\n";
784

    
785
		$javascript .= "function myResume() {\n";
786
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null)\n";
787
		$javascript .= "document.layers['shaperarea'].visibility = 'visible';\n";
788
		$javascript .= "else if (document.all)\n";
789
		$javascript .= "document.all['shaperarea'].style.visibility = 'visible';\n";
790
		$javascript .= "}\n";
791
		$javascript .= "</script>";
792
		
793
		return $javascript;
794
	}
795
	
796
	/* 
797
	 * Currently this will not be called unless we decide to clonce whole 
798
	 * queue tree on the 'By Queues' view or support drag&drop on the tree/list
799
	 */
800
	 function copy_queue($interface, &$cflink) {
801

    
802
 		$cflink['name'] = $this->GetQname();
803
                $cflink['interface'] = $interface;
804
                $cflink['qlimit'] = $this->GetQlimit();
805
                $cflink['priority'] = $this->GetQpriority();
806
                $cflink['description'] = $this->GetDescription();
807
                $cflink['enabled'] = $this->GetEnabled();
808
                $cflink['default'] = $this->GetDefault();
809
                $cflink['red'] = $this->GetRed();
810
                $cflink['rio'] = $this->GetRio();
811
                $cflink['ecn'] = $this->GetEcn();
812

    
813
                if (is_array($this->subqueues)) {
814
                        $cflinkp['queue'] = array();
815
                        foreach ($this->subqueues as $q) {
816
				 $cflink['queue'][$q->GetQname()] = array();
817
                                $q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
818
			}
819
                }
820

    
821
	 }
822

    
823
	function clean_queue($sched) {
824
		clean_child_queues($sched, $this->GetLink());
825
		if (is_array($this->subqueues)) {
826
				foreach ($this->subqueues as $q)
827
						$q->clean_queue($sched);
828
				}
829
		}
830

    
831

    
832
		
833
        function &get_queue_list(&$qlist) {
834
                        $qlist[$this->GetQname()] = & $this;
835
                        if (is_array($this->subqueues)) {
836
                                foreach ($this->subqueues as $queue)
837
                                        $queue->get_queue_list($qlist);
838
                        }
839
        }
840

    
841
	function delete_queue() {
842
		unref_on_altq_queue_list($this->GetQname());
843
		if ($this->GetDefault())
844
				altq_set_default_queue($this->GetInterface(), "false");
845
		cleanup_queue_from_rules($this->GetQname());
846
		unset_object_by_reference($this->GetLink());
847
	}
848
	
849
	function delete_all() {
850
                if (count($this->subqueues)) {
851
                        foreach ($this->subqueues as $q) {
852
                                $q->delete_all();
853
                                unset_object_by_reference($q->GetLink());
854
                                unset($q);
855
                        }
856
                        unset($this->subqueues);
857
                }
858
        }
859

    
860
	 function &find_queue($interface, $qname) { 
861
		if ($qname == $this->GetQname())
862
			return $this; 
863
	}
864
	
865
	function find_parentqueue($interface, $qname) { return; }
866
		
867
	function validate_input($data, &$input_errors) {
868
	
869
		$reqfields[] = "name";
870
		$erqfieldsn[] = "Name";
871
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
872

    
873
		if ($data['priority'] && (!is_numeric($data['priority'])
874
						|| ($data['priority'] < 1) || ($data['priority'] > 15))) {
875
					$input_errors[] = "The priority must be an integer between 1 and 15.";
876
		}
877
		if ($data['qlimit'] && (!is_numeric($data['qlimit']))) 
878
				$input_errors[] = "Queue limit must be an integer";
879
		if ($data['qlimit'] < 0)
880
				$input_errors[] = "Queue limit must be positive";
881
		if (!preg_match("/^[a-zA-Z0-9_-]*$/", $data['name']))
882
			 $input_errors[] = "Queue names must be alphanumeric and _ or - only.";
883
		
884
	}
885

    
886
	function ReadConfig(&$q) {
887
		if (isset($q['name']))
888
				$this->SetQname($q['name']);
889
		if (isset($q['interface']))
890
				$this->SetInterface($q['interface']);
891
		if ($q['bandwidth'] <> "") {
892
			$this->SetBandwidth($q['bandwidth']);
893
			if ($q['bandwidthtype'] <> "")
894
				$this->SetBwscale($q['bandwidthtype']);
895
		}
896
		if (isset($q['qlimit']) && $q['qlimit'] <> "")
897
					$this->SetQlimit($q['qlimit']);
898
				if (isset($q['priority']))
899
						$this->SetQPriority($q['priority']);
900
				if (isset($q['description']) && $q['description'] != "")
901
						$this->SetDescription($q['description']);
902
		if (isset($q['ftpqueue']) && $q['ftpqueue'] <> "") 
903
			set_is_ftp_queue($this->GetInterface(), $this->GetQname());
904
		$this->SetRed($q['red']);
905
		$this->SetRio($q['rio']);
906
		$this->SetEcn($q['ecn']);
907
		$this->SetDefault($q['default']);
908
		$this->SetEnabled($q['enabled']);
909

    
910
		}
911

    
912
	function build_tree() {
913
			$tree = " <li><a href=\"firewall_shaper.php?interface=". $this->GetInterface()."&queue=". $this->GetQname()."&action=show"; 
914
			$tree .= "\" ";
915
			if ($this->GetDefault())
916
				$tree .= " class=\"navlnk\"";
917
			$tree .= " >" . $this->GetQname() . "</a>";
918
			/* 
919
			 * Not needed here!
920
			 * if (is_array($queues) {
921
			 *	  $tree .= "<ul>";
922
			 *	  foreach ($q as $queues) 
923
			 *		  $tree .= $queues['$q->GetName()']->build_tree();
924
			 *	  endforeach	
925
			 *	  $tree .= "</ul>";
926
			 * }
927
			 */
928

    
929
			$tree .= "</li>"; 
930

    
931
			return $tree;
932
		}
933
		
934
		/* Should return something like:
935
		 * queue $qname on $qinterface bandwidth ....
936
		 */
937
		function build_rules() {
938
				$pfq_rule = " queue ". $this->qname;
939
				if ($this->GetInterface())
940
						$pfq_rule .= " on ".convert_friendly_interface_to_real_interface_name($this->GetInterface());
941
				if ($this->GetQpriority())
942
						$pfq_rule .= " priority ".$this->GetQpriority();
943
				if ($this->GetQlimit())
944
						$pfq_rule .= " qlimit " . $this->GetQlimit();
945
				if ($this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetDefault()) {
946
						$pfq_rule .= " priq ( ";
947
					if ($this->GetRed()) {
948
						$comma = 1;
949
						$pfq_rule .= " red ";
950
					}
951
					if ($this->GetRio()) {
952
						if ($comma) 
953
								$pfq_rule .= " ,";
954
						$comma = 1;
955
						$pfq_rule .= " rio ";
956
					}
957
					if ($this->GetEcn()) {
958
						if ($comma) 
959
								$pfq_rule .= " ,";
960
						$comma = 1;
961
						$pfq_rule .= " ecn ";
962
					}	
963
					if ($this->GetDefault()) {
964
						if ($comma)
965
							$pfq_rule .= " ,";
966
						$pfq_rule .= " default ";
967
					}
968
					$pfq_rule .= " ) ";
969
				}
970
	
971
				$pfq_rule .= " \n";
972
		
973
				return $pfq_rule;
974
		}
975

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

    
1043
		return $form;
1044
		}
1045

    
1046
	function build_shortform() {
1047
		/* XXX: Hacks in site. Mostly layer violations!  */
1048
		global $g, $altq_list_queues;
1049

    
1050
		$altq =& $altq_list_queues[$this->GetInterface()];
1051
		if ($altq)
1052
			$scheduler = ": " . $altq->GetScheduler();
1053
		 $form = "<tr><td width=\"20%\" class=\"vtable\">";
1054
		$form .= "<a href=\"firewall_shaper.php?interface" . $this->GetInterface() . "&queue=" . $this->GetInterface()."&action=show\">".$this->GetInterface().": ".$scheduler."</a>";
1055
		$form .= "</td></tr>";
1056
		/* 
1057
		 * XXX: Hack in sight maybe fix with a class that wraps all
1058
		 * of this layer violations
1059
		 */
1060
		$form .= "<tr>";
1061
		$form .= "<td width=\"50%\" class=\"vncellreq\">";
1062
		$form .= "Bandwidth: " . $this->GetBandwidth().$this->GetBwscale();
1063
		$form .= "</td><td width=\"50%\"></td></tr>";
1064
		$form .= "<tr><td width=\"20%\" class=\"vncellreq\">";
1065
		if ($this->GetQpriority())
1066
			$form .= "Priority: on </td></tr>";
1067
		if ($this->GetDefault())
1068
			$form .= "<tr><td class=\"vncellreq\">Default: on </td></tr>";
1069
		$form .= "<tr><td width=\"20%\" class=\"vncellreq\">";
1070
		$form .= "<a href=\"firewall_shaper_queues.php?interface=";
1071
			$form .= $this->GetInterface() . "&queue=";
1072
			$form .= $this->GetQname() . "&action=delete\">";
1073
			$form .= "<img src=\"";
1074
			$form .= "./themes/".$g['theme']."/images/icons/icon_x.gif\"";
1075
			$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Delete queue from interface\">";
1076
			$form .= "<span>Delete queue from interface</span></a></td></tr>";
1077
		
1078
		return $form;
1079

    
1080
	}
1081

    
1082
		function update_altq_queue_data(&$q) { 
1083
		$this->ReadConfig($q);
1084
	}
1085

    
1086
		function wconfig() {
1087
				$cflink =& get_reference_to_me_in_config($this->GetLink());
1088
		if (!is_array($cflink))
1089
			$cflink = array();
1090
		$cflink['name'] = $this->GetQname();
1091
				$cflink['interface'] = $this->GetInterface();
1092
				$cflink['qlimit'] = $this->GetQlimit();
1093
				$cflink['priority'] = $this->GetQpriority();
1094
		$cflink['description'] = $this->GetDescription();
1095
		$cflink['enabled'] = $this->GetEnabled();
1096
		$cflink['default'] = $this->GetDefault();
1097
		$cflink['red'] = $this->GetRed();
1098
		$cflink['rio'] = $this->GetRio();
1099
		$cflink['ecn'] = $this->GetEcn();
1100
	}
1101
}
1102

    
1103
class hfsc_queue extends priq_queue {
1104
		/* realtime */
1105
	var $realtime;
1106
		var $r_m1;
1107
		var $r_d;
1108
		var $r_m2;
1109
		/* linkshare */
1110
	var $linkshare;
1111
		var $l_m1;
1112
		var $l_d;
1113
		var $l_m2;
1114
		/* upperlimit */
1115
	var $upperlimit;
1116
		var $u_m1;
1117
		var $u_d;
1118
		var $u_m2;
1119

    
1120
		/*
1121
		 * HFSC can have nested queues.
1122
		 */
1123

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

    
1209

    
1210

    
1211
		function &add_queue($interface, &$qname, &$path, &$input_errors) {
1212

    
1213
			if (!is_array($this->subqueues))
1214
							$this->subqueues = array();
1215
			$q =& new hfsc_queue();
1216
			$q->SetInterface($this->GetInterface());
1217
			$q->SetParent(&$this);
1218
			$q->ReadConfig($qname);
1219
			$q->validate_input($qname, $input_errors);
1220
			if (count($input_errors)) {
1221
				return $q;
1222
			}
1223
			
1224
			$q->SetEnabled("on");
1225
			$q->SetLink($path);
1226
			switch ($q->GetBwscale()) {
1227
                        case "%":
1228
                                $myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
1229
                                break;
1230
                        default:
1231
                                $myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
1232
                                break;
1233
                	}
1234
                        $q->SetAvailableBandwidth($myBw);
1235
                        $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
1236

    
1237
			$this->subqueues[$q->GetQname()] =& $q; //new hfsc_queue()
1238
			ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
1239
			if (is_array($qname['queue'])) {
1240
				foreach ($qname['queue'] as $key1 => $que) {
1241
					array_push($path, $key1);
1242
								$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
1243
					array_pop($path);
1244
				}
1245
					}
1246
	
1247
			return $q;
1248
		}
1249

    
1250
 	        function copy_queue($interface, &$cflink) {
1251

    
1252
                        $cflink['name'] = $this->GetQname();
1253
                        $cflink['interface'] = $interface;
1254
                        $cflink['qlimit'] = $this->GetQlimit();
1255
                        $cflink['priority'] = $this->GetQpriority();
1256
                        $cflink['description'] = $this->GetDescription();
1257
                        $cflink['bandwidth'] = $this->GetBandwidth();
1258
                        $cflink['bandwidthtype'] = $this->GetBwscale();
1259
                        $cflink['enabled'] = $this->GetEnabled();
1260
                        $cflink['default'] = $this->GetDefault();
1261
                        $cflink['red'] = $this->GetRed();
1262
                        $cflink['rio'] = $this->GetRio();
1263
                        $cflink['ecn'] = $this->GetEcn();
1264
                        if ($this->GetLinkshare() <> "") {
1265
                                if ($this->GetL_m1() <> "") {
1266
                                        $cflink['linkshare1'] = $this->GetL_m1();
1267
                                        $cflink['linkshare2'] = $this->GetL_d();
1268
                                        $cflink['linkshare'] = "on";
1269
                                }
1270
                                if ($this->GetL_m2() <> "") {
1271
                                        $cflink['linkshare3'] = $this->GetL_m2();
1272
                                        $cflink['linkshare'] = "on";
1273
                                }
1274
                        } else $cflink['linkshare'] = "";
1275
                        if ($this->GetRealtime() <> "") {
1276
                                if ($this->GetR_m1() <> "") {
1277
                                        $cflink['realtime1'] = $this->GetR_m1();
1278
                                        $cflink['realtime2'] = $this->GetR_d();
1279
                                        $cflink['realtime'] = "on";
1280
                                }
1281
                                if ($this->GetR_m2() <> "") {
1282
                                        $cflink['realtime3'] = $this->GetR_m2();
1283
                                        $cflink['realtime'] = "on";
1284
                                }
1285
                        } else $cflink['realtime'] = "";
1286
                        if ($this->GetUpperlimit() <> "") {
1287
                                if ($this->GetU_m1() <> "") {
1288
                                        $cflink['upperlimit1'] = $this->GetU_m1();
1289
                                        $cflink['upperlimit2'] = $this->GetU_d();
1290
                                        $cflink['upperlimit'] = "on";
1291
                                }
1292
                                if ($this->GetU_m2() <> "") {
1293
                                        $cflink['upperlimit3'] = $this->GetU_m2();
1294
                                        $cflink['upperlimit'] = "on";
1295
                                }
1296
                        } else $cflink['upperlimit'] = "";
1297

    
1298
	                if (is_array($this->subqueues)) {
1299
        	                $cflinkp['queue'] = array();
1300
                	        foreach ($this->subqueues as $q) {
1301
                	                 $cflink['queue'][$q->GetQname()] = array();
1302
        	                        $q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
1303
				}
1304
                	}
1305

    
1306
         	}
1307

    
1308
		function delete_queue() { 
1309
			unref_on_altq_queue_list($this->GetQname());
1310
			if ($this->GetDefault()) 
1311
				altq_set_default_queue($this->GetInterface(), "false");
1312
			cleanup_queue_from_rules($this->GetQname());
1313
			$parent =& $this->GetParent();
1314
			foreach ($this->subqueues as $q)  {
1315
			$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
1316
				$q->delete_queue();
1317
			}
1318
			unset_object_by_reference($this->GetLink());
1319
			}
1320
	
1321
			/*
1322
			 * Should search even its childs
1323
			 */
1324
			function &find_queue($interface, $qname) {
1325
					if ($qname == $this->GetQname()) 
1326
							return $this;
1327
		
1328
					foreach ($this->subqueues as $q) {
1329
							$result =& $q->find_queue("", $qname);
1330
				if ($result)
1331
									return $result;
1332
					}
1333
			}
1334

    
1335
	function &find_parentqueue($interface, $qname) {
1336
		if ($this->subqueues[$qname]) 
1337
			return $this;
1338
				foreach ($this->subqueues as $q) {
1339
					$result = $q->find_parentqueue("", $qname);
1340
			if ($result)
1341
				return $result;
1342
		}
1343
		}
1344
	
1345
	function validate_input($data, &$input_errors) {
1346
		parent::validate_input($data, $input_errors);
1347
		
1348
		$reqfields[] = "bandwidth";
1349
		$reqdfieldsn[] = "Bandwidth";
1350
		$reqfields[] = "bandwidthtype";
1351
		$reqdfieldsn[] = "Bandwidthtype";
1352

    
1353
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
1354
		
1355
		if (isset($data['linkshare3']) && $data['linkshare3'] <> "") {
1356
		if ($data['bandwidth'] && (!is_numeric($data['bandwidth'])))
1357
                        $input_errors[] = "Bandwidth must be an integer.";
1358

    
1359
                if ($data['bandwidth'] < 0)
1360
                        $input_errors[] = "Bandwidth cannot be negative.";
1361

    
1362
                if ($data['bandwidthtype'] == "%") {
1363
                 if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
1364
                       $input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
1365
                 }
1366
/*
1367
                $parent =& $this->GetParent();
1368
                switch ($data['bandwidthtype']) {
1369
                       case "%":
1370
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
1371
                       default:
1372
                             $mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
1373
                             break;
1374
                }
1375
                if ($parent->GetAvailableBandwidth() < $myBw)
1376
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
1377
*/
1378
                if ($data['priority'] > 7)
1379
                        $input_errors[] = "Priority must be an integer between 1 and 7.";
1380
		}
1381

    
1382
		if ($data['upperlimit1'] <> "" &&  $data['upperlimit2'] == "")
1383
			$input_errors[] = ("upperlimit service curve defined but missing (d) value");
1384
		if ($data['upperlimit2'] <> "" &&  $data['upperlimit1'] == "")
1385
			$input_errors[] = ("upperlimit service curve defined but missing initial bandwidth (m1) value");
1386
		if ($data['upperlimit1'] <> "" && !is_valid_shaperbw($data['upperlimit1']))
1387
			$input_errors[] = ("upperlimit m1 value needs to be Kb, Mb, Gb, or %");
1388
		if ($data['upperlimit2'] <> "" && !is_numeric($data['upperlimit2']))
1389
			$input_errors[] = ("upperlimit d value needs to be numeric");
1390
		if ($data['upperlimit3'] <> "" && !is_valid_shaperbw($data['upperlimit3']))
1391
			$input_errors[] = ("upperlimit m2 value needs to be Kb, Mb, Gb, or %");
1392
/*
1393

    
1394
		if (isset($data['upperlimit']) && $data['upperlimit3'] <> "" && $data['upperlimit1'] <> "") {
1395
		$bw_1 = get_hfsc_bandwidth($this, $data['upperlimit1']);
1396
		$bw_2 = get_hfsc_bandwidth($this, $data['upperlimit3']);
1397
		if (floatval($bw_1) < floatval($bw_2)) 
1398
			$input_errors[] = ("upperlimit m1 cannot be smaller than m2");
1399

    
1400
		
1401
		if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1402
			$input_errors[] = ("upperlimit specification excedd 80% of allowable allocation.");
1403
		}
1404
*/
1405
		if ($data['linkshare1'] <> "" &&  $data['linkshare2'] == "")
1406
			$input_errors[] = ("linkshare service curve defined but missing (d) value");
1407
		if ($data['linkshare2'] <> "" &&  $data['linkshare1'] == "")
1408
			$input_errors[] = ("linkshare service curve defined but missing initial bandwidth (m1) value");
1409
		if ($data['linkshare1'] <> "" && !is_valid_shaperbw($data['linkshare1']))
1410
			$input_errors[] = ("linkshare m1 value needs to be Kb, Mb, Gb, or %");
1411
		if ($data['linkshare2'] <> "" && !is_numeric($data['linkshare2']))
1412
			$input_errors[] = ("linkshare d value needs to be numeric");
1413
		if ($data['linkshare3'] <> "" && !is_valid_shaperbw($data['linkshare3']))
1414
			$input_errors[] = ("linkshare m2 value needs to be Kb, Mb, Gb, or %");
1415
		if ($data['realtime1'] <> "" &&  $data['realtime2'] == "")
1416
			$input_errors[] = ("realtime service curve defined but missing (d) value");
1417
		if ($data['realtime2'] <> "" &&  $data['realtime1'] == "")
1418
			$input_errors[] = ("realtime service curve defined but missing initial bandwidth (m1) value");
1419

    
1420
/*
1421
		if (isset($data['linkshare']) && $data['linkshare3'] <> "" && $data['linkshare1'] <> "" && 0) {
1422
		$bw_1 = get_hfsc_bandwidth($this, $data['linkshare1']);
1423
                $bw_2 = get_hfsc_bandwidth($this, $data['linkshare3']);
1424
                if (floatval($bw_1) < floatval($bw_2))
1425
                        $input_errors[] = ("linkshare m1 cannot be smaller than m2");
1426

    
1427

    
1428
                if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1429
                        $input_errors[] = ("linkshare specification excedd 80% of allowable allocation.");
1430
		}
1431
*/
1432

    
1433
		if ($data['realtime1'] <> "" && !is_valid_shaperbw($data['realtime1']))
1434
			$input_errors[] = ("realtime m1 value needs to be Kb, Mb, Gb, or %");
1435
		if ($data['realtime2'] <> "" && !is_numeric($data['realtime2']))
1436
			$input_errors[] = ("realtime d value needs to be numeric");
1437
		if ($data['realtime3'] <> "" && !is_valid_shaperbw($data['realtime3']))
1438
			$input_errors[] = ("realtime m2 value needs to be Kb, Mb, Gb, or %");
1439

    
1440
/*
1441
		if (isset($data['realtime']) && $data['realtime3'] <> "" && $data['realtime1'] <> "" && 0) {
1442
		$bw_1 = get_hfsc_bandwidth($this, $data['realtime1']);
1443
                $bw_2 = get_hfsc_bandwidth($this, $data['realtime3']);
1444
                if (floatval($bw_1) < floatval($bw_2))
1445
                        $input_errors[] = ("realtime m1 cannot be smaller than m2");
1446

    
1447

    
1448
                if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1449
                        $input_errors[] = ("realtime specification excedd 80% of allowable allocation.");
1450
		}
1451
*/
1452

    
1453
	}
1454

    
1455
		function ReadConfig(&$cflink) {
1456
		if (isset($cflink['linkshare']) && $cflink['linkshare'] <> "") {
1457
			if (isset($cflink['linkshare1']) && $cflink['linkshare1'] <> "") {
1458
				$this->SetL_m1($cflink['linkshare1']);
1459
                                $this->SetL_d($cflink['linkshare2']);
1460
				$this->SetLinkshare();
1461
			}
1462
			if (isset($cflink['linkshare3']) && $cflink['linkshare3'] <> "") {
1463
                                $this->SetL_m2($cflink['linkshare3']);
1464
				$this->SetLinkshare();
1465
			}
1466
		} else $this->DisableLinkshare();
1467
		if (isset($cflink['realtime']) && $cflink['realtime'] <> "") {
1468
                        if (isset($cflink['realtime1']) && $cflink['realtime1'] <> "") {
1469
                                $this->SetR_m1($cflink['realtime1']);
1470
                                $this->SetR_d($cflink['realtime2']);
1471
				$this->SetRealtime();
1472
			}
1473
                        if (isset($cflink['realtime3']) && $cflink['realtime3'] <> "") {
1474
                                $this->SetR_m2($cflink['realtime3']);
1475
				$this->SetRealtime();
1476
			}
1477
		} else $this->DisableRealtime(); 
1478
		if (isset($cflink['upperlimit']) && $cflink['upperlimit'] <> "") {
1479
                        if (isset($cflink['upperlimit1']) && $cflink['upperlimit1'] <> "") {
1480
                                $this->SetU_m1($cflink['upperlimit1']);
1481
                                $this->SetU_d($cflink['upperlimit2']);
1482
				$this->SetUpperlimit();
1483
			}
1484
                        if (isset($cflink['upperlimit3']) && $cflink['upperlimit3'] <> "") {
1485
                                $this->SetU_m2($cflink['upperlimit3']);
1486
				$this->SetUpperlimit();
1487
			}
1488
		} else $this->DisableUpperlimit();
1489
		parent::ReadConfig($cflink);
1490

    
1491
		}
1492

    
1493
	function build_tree() {
1494
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface() ."&queue=" . $this->GetQname()."&action=show"; 
1495
		$tree .= "\" ";
1496
		if ($this->GetDefault())
1497
								$tree .= " class=\"navlnk\"";
1498
		$tree .= " >" . $this->GetQname() . "</a>";
1499
		if (is_array($this->subqueues)) {
1500
			$tree .= "<ul>";
1501
			foreach ($this->subqueues as $q)  {
1502
				$tree .= $q->build_tree();
1503
			}	
1504
			$tree .= "</ul>";
1505
		}
1506
		$tree .= "</li>";
1507
		return $tree;
1508
	}
1509

    
1510
		/* Even this should take childs in consideration */
1511
		function build_rules() {
1512

    
1513
				$pfq_rule = " queue ". $this->qname;
1514
				if ($this->GetInterface())
1515
						$pfq_rule .= " on ".convert_friendly_interface_to_real_interface_name($this->GetInterface());
1516
		if ($this->GetBandwidth() && $this->GetBwscale())
1517
						$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
1518
					
1519
				if ($this->GetQpriority())
1520
						$pfq_rule .= " priority " . $this->GetQpriority();
1521
				if ($this->GetQlimit())
1522
						$pfq_rule .= " qlimit " . $this->GetQlimit();
1523
		  if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetRealtime() <> "" || $this->GetLinkshare() <> "" || $this->GetUpperlimit() <> "") {
1524
						$pfq_rule .= " hfsc ( ";
1525
						if ($this->GetRed()) {
1526
								$comma = 1;
1527
								$pfq_rule .= " red ";
1528
						}
1529
						if ($this->GetRio()) {
1530
								if ($comma) 
1531
										$pfq_rule .= " ,";
1532
								$comma = 1;
1533
								$pfq_rule .= " rio ";
1534
						}
1535
						if ($this->GetEcn()) {
1536
								if ($comma) 
1537
										$pfq_rule .= " ,";
1538
								$comma = 1;
1539
								$pfq_rule .= " ecn ";
1540
						}
1541
						if ($this->GetDefault()) {
1542
								if ($comma)
1543
										$pfq_rule .= " ,";
1544
								$comma = 1;
1545
								$pfq_rule .= " default ";
1546
						}
1547

    
1548
						if ($this->GetRealtime() <> "")  {
1549
				if ($comma) 
1550
									$pfq_rule .= " , ";
1551
				if ($this->GetR_m1()  <> "" && $this->GetR_d() <> "" && $this->GetR_m2() <> "")
1552
			$pfq_rule .= " realtime (".$this->GetR_m1() . ", " . $this->GetR_d().", ". $this->GetR_m2() .") ";
1553
				else  if ($this->GetR_m2() <> "")
1554
					$pfq_rule .= " realtime " . $this->GetR_m2();
1555
				$comma = 1;
1556
			}
1557
						if ($this->GetLinkshare() <> "") {
1558
								if ($comma)
1559
					$pfq_rule .= " ,";
1560
				if ($this->GetL_m1() <> "" && $this->GetL_d() <> "" && $this->GetL_m2() <> "")
1561
			$pfq_rule .= " linkshare (".$this->GetL_m1(). ", ". $this->GetL_d(). ", ". $this->GetL_m2(). ") ";
1562
				else if ($this->GetL_m2() <> "")
1563
					$pfq_rule .= " linkshare " . $this->GetL_m2() . " ";
1564
				$comma = 1;
1565
			}
1566
						if ($this->GetUpperlimit() <> "") {
1567
				if ($comma)
1568
					$pfq_rule .= " ,";
1569
				if ($this->GetU_m1() <> "" && $this->GetU_d() <> "" && $this->GetU_m2() <> "")
1570
							$pfq_rule .= " upperlimit (".$this->GetU_m1().", ". $this->GetU_d().", ". $this->GetU_m2(). ") ";
1571
				else if ($this->GetU_m2() <> "")
1572
					$pfq_rule .= " upperlimit " . $this->GetU_m2() . " ";
1573
			}
1574
					$pfq_rule .= " ) ";
1575
					}
1576
					if (count($this->subqueues)) {
1577
						$i = count($this->subqueues);
1578
						$pfq_rule .= " { ";
1579
						foreach ($this->subqueues as $qkey => $qnone) {
1580
								if ($i > 1) {
1581
										$i--;
1582
										$pfq_rule .= " {$qkey}, ";
1583
								} else
1584
										$pfq_rule .= " {$qkey} ";
1585
						}
1586
								$pfq_rule .= " } \n";
1587
								foreach ($this->subqueues as $q)
1588
									$pfq_rule .= $q->build_rules();
1589
					}
1590

    
1591
				 $pfq_rule .= " \n";
1592
			
1593
				return $pfq_rule;
1594
		}
1595

    
1596
	function build_javascript() {
1597
		$javascript = parent::build_javascript();
1598
		$javascript .= "<script type=\"text/javascript\">";
1599
		$javascript .= "function enable_realtime(enable_over) { \n";
1600
		$javascript .= "if (document.iform.realtime.checked || enable_over) { \n";
1601
		$javascript .= "document.iform.realtime1.disabled = 0;\n";
1602
		$javascript .= "document.iform.realtime2.disabled = 0;\n";
1603
		$javascript .= "document.iform.realtime3.disabled = 0;\n";
1604
		$javascript .= " } else { \n";
1605
		$javascript .= "document.iform.realtime1.disabled = 1;\n";
1606
		$javascript .= "document.iform.realtime2.disabled = 1;\n";
1607
		$javascript .= "document.iform.realtime3.disabled = 1;\n";
1608
		$javascript .= " } \n";
1609
		$javascript .= " } \n";
1610
		$javascript .= "function enable_linkshare(enable_over) { \n";
1611
		$javascript .= "if (document.iform.linkshare.checked || enable_over) { \n";
1612
		$javascript .= "document.iform.linkshare1.disabled = 0;\n";
1613
		$javascript .= "document.iform.linkshare2.disabled = 0;\n";
1614
		$javascript .= "document.iform.linkshare3.disabled = 0;\n";
1615
		$javascript .= " } else { \n";
1616
		$javascript .= "document.iform.linkshare1.disabled = 1;\n";
1617
		$javascript .= "document.iform.linkshare2.disabled = 1;\n";
1618
		$javascript .= "document.iform.linkshare3.disabled = 1;\n";
1619
		$javascript .= " } \n";
1620
		$javascript .= " } \n";
1621
		$javascript .= "function enable_upperlimit(enable_over) { \n";
1622
		$javascript .= "if (document.iform.upperlimit.checked || enable_over) { \n";
1623
		$javascript .= "document.iform.upperlimit1.disabled = 0;\n";
1624
		$javascript .= "document.iform.upperlimit2.disabled = 0;\n";
1625
		$javascript .= "document.iform.upperlimit3.disabled = 0;\n";
1626
		$javascript .= " } else { \n";
1627
		$javascript .= "document.iform.upperlimit1.disabled = 1;\n";
1628
		$javascript .= "document.iform.upperlimit2.disabled = 1;\n";
1629
		$javascript .= "document.iform.upperlimit3.disabled = 1;\n";
1630
		$javascript .= " } \n";
1631
			
1632
		$javascript .= "} \n";
1633
		$javascript .= "</script>";
1634

    
1635
		return $javascript;
1636
	}
1637

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

    
1730
				return $form;
1731
		}
1732

    
1733
	function update_altq_queue_data(&$data) { 
1734
		$this->ReadConfig($data);
1735
	}
1736

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

    
1789
class cbq_queue extends priq_queue {
1790
		var $qborrow;
1791

    
1792
	function GetBorrow() {
1793
		return $this->qborrow;
1794
	}
1795
	function SetBorrow($borrow) {
1796
		$this->qborrow = $borrow;
1797
	}
1798
	function CanHaveChilds() {
1799
			return true;
1800
	}
1801

    
1802
	function &add_queue($interface, &$qname, &$path, &$input_errors) {
1803

    
1804
		if (!is_array($this->subqueues))
1805
						$this->subqueues = array();
1806
		$q =& new cbq_queue();
1807
		$q->SetInterface($this->GetInterface());
1808
		$q->SetParent(&$this);
1809
		$q->ReadConfig($qname);
1810
                $q->validate_input($qname, $input_errors);
1811
                if (count($input_errors)) {
1812
                        return $q;
1813
                }
1814
                switch ($q->GetBwscale()) {
1815
                        case "%":
1816
                                $myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
1817
                                break;
1818
                        default:
1819
                                $myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
1820
                                break;
1821
                }
1822
                $q->SetAvailableBandwidth($myBw);
1823
                $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
1824

    
1825
		$q->SetEnabled("on");
1826
		$q->SetLink($path);
1827
		$this->subqueues[$q->GetQName()] = &$q;
1828
		ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
1829
		if (is_array($qname['queue'])) {
1830
				foreach ($qname['queue'] as $key1 => $que) {
1831
						array_push($path, $key1);
1832
						$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
1833
						array_pop($path);
1834
				}
1835
		}
1836

    
1837
		return $q;
1838
		}
1839

    
1840
		function copy_queue($interface, &$cflink) {
1841

    
1842
                                $cflink['interface'] = $interface;
1843
                                $cflink['qlimit'] = $this->GetQlimit();
1844
                                $cflink['priority'] = $this->GetQpriority();
1845
                                $cflink['name'] = $this->GetQname();
1846
                                $cflink['description'] = $this->GetDescription();
1847
                                $cflink['bandwidth'] = $this->GetBandwidth();
1848
                                $cflink['bandwidthtype'] = $this->GetBwscale();
1849
                                $cflink['enabled'] = $this->GetEnabled();
1850
                                $cflink['default'] = $this->GetDefault();
1851
                                $cflink['red'] = $this->GetRed();
1852
                                $cflink['rio'] = $this->GetRio();
1853
                                $cflink['ecn'] = $this->GetEcn();
1854
                                $cflink['borrow'] = $this->GetBorrow();
1855
                		if (is_array($this->queues)) {
1856
 		                       $cflinkp['queue'] = array();
1857
                        		foreach ($this->subqueues as $q) {
1858
 		                                $cflink['queue'][$q->GetQname()] = array();
1859
                		                $q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
1860
					}
1861
                		}
1862

    
1863
		}
1864
	
1865
		/*
1866
		 * Should search even its childs
1867
		 */
1868
		function &find_queue($interface, $qname) {
1869
				if ($qname == $this->GetQname())
1870
						return $this;
1871
				foreach ($this->subqueues as $q) {
1872
						$result =& $q->find_queue("", $qname);
1873
			if ($result)
1874
								return $result;
1875
				}
1876
		}
1877

    
1878
	function &find_parentqueue($interface, $qname) {
1879
				if ($this->subqueues[$qname])
1880
						return $this;
1881
				foreach ($this->subqueues as $q) {
1882
					$result = $q->find_parentqueue("", $qname);
1883
			if ($result)
1884
				return $result;
1885
		}
1886
		}
1887

    
1888
		function delete_queue() {
1889
			unref_on_altq_queue_list($this->GetQname());
1890
			if ($this->GetDefault())
1891
				altq_set_default_queue($this->GetInterface(), "false");
1892
			cleanup_queue_from_rules($this->GetQname());
1893
			foreach ($this->subqueues as $q) {
1894
			$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
1895
				$q->delete_queue();
1896
			}
1897
			unset_object_by_reference($this->GetLink());
1898
		}
1899
	
1900
	function validate_input($data, &$input_errors) {
1901
		parent::validate_input($data, $input_errors);
1902
		
1903
		if ($data['priority'] > 7)
1904
				$input_errors[] = "Priority must be an integer between 1 and 7.";
1905
		$reqfields[] = "bandwidth";
1906
		$reqdfieldsn[] = "Bandwidth";
1907
		$reqfields[] = "bandwidthtype";
1908
		$reqdfieldsn[] = "Bandwidthtype";
1909

    
1910
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
1911
		
1912
		if ($data['bandwidth'] && !is_numeric($data['bandwidth']))
1913
                 $input_errors[] = "Bandwidth must be an integer.";
1914

    
1915

    
1916
           if ($data['bandwidth'] < 0)
1917
                       $input_errors[] = "Bandwidth cannot be negative.";
1918

    
1919

    
1920
           if ($data['bandwidthtype'] == "%") {
1921
                 if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
1922
                       $input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
1923
           }
1924

    
1925
/*
1926
           $parent =& $this->GetParent();
1927
           switch ($data['bandwidthtype']) {
1928
                       case "%":
1929
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
1930
                       default:
1931
                             $mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
1932
                             break;
1933
           }
1934
                if ($parent->GetAvailableBandwidth() < floatval($myBw))
1935
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
1936
*/
1937
	}
1938
		function ReadConfig(&$q) {
1939
				parent::ReadConfig($q);
1940
		if ($q['borrow'])
1941
			$this->SetBorrow("on");
1942
		}
1943
		
1944
	function build_javascript() {
1945
		return parent::build_javascript();
1946
	}
1947

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

    
2022
			$pfq_rule .= " \n";
2023
			return $pfq_rule;
2024
	}
2025

    
2026
	function build_form() {
2027
		$form = "<tr>";
2028
		$form .= "<td valign=\"top\" class=\"vncellreq\">Bandwidth</td>";
2029
		$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
2030
		if ($this->GetBandwidth() > 0)
2031
				$form .= htmlspecialchars($this->GetBandwidth());
2032
		$form .= "\">";
2033
		$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
2034
		$form .= "<option value=\"Gb\"";
2035
		if ($this->GetBwscale() == "Gb")
2036
				$form .= " selected=\"yes\"";
2037
		$form .= ">Gbit/s</option>";
2038
		$form .= "<option value=\"Mb\"";
2039
		if ($this->GetBwscale() == "Mb")
2040
				$form .= " selected=\"yes\"";
2041
		$form .= ">Mbit/s</option>";
2042
		$form .= "<option value=\"Kb\"";
2043
		if ($this->GetBwscale() == "Kb")
2044
				$form .= " selected=\"yes\"";
2045
		$form .= ">Kbit/s</option>";
2046
		$form .= "<option value=\"\"";
2047
		if ($this->GetBwscale() == "b")
2048
				$form .= " selected=\"yes\"";
2049
		$form .= ">Bit/s</option>";
2050
		$form .= "<option value=\"%\"";
2051
		if ($this->GetBwscale() == "%")
2052
				$form .= " selected=\"yes\"";
2053
		$form .= ">%</option>";
2054
		$form .= "</select> <br>";
2055
		$form .= "<span class=\"vexpl\">Choose the amount of bandwidth for this queue";
2056
		$form .= "</span></td></tr>";
2057
		$form .= parent::build_form();
2058
		$form .= "<tr><td class=\"vncellreq\">Scheduler specific options</td>";
2059
		$form .= "<td class=\"vtable\"><input type=\"checkbox\" id=\"borrow\" name=\"borrow\"";
2060
			if($this->GetBorrow() == "on") 
2061
		$form .=  " CHECKED ";
2062
		$form .= "> Borrow from other queues when available<br></td></tr>";
2063

    
2064
		return $form;
2065
	}
2066

    
2067
	function update_altq_queue_data(&$data) { 
2068
		$this->ReadConfig($data);
2069
	}
2070

    
2071
	function wconfig() {
2072
		$cflink =& get_reference_to_me_in_config($this->GetLink());
2073
				if (!is_array($cflink))
2074
						$cflink = array();
2075
				$cflink['interface'] = $this->GetInterface();
2076
				$cflink['qlimit'] = $this->GetQlimit();
2077
				$cflink['priority'] = $this->GetQpriority();
2078
				$cflink['name'] = $this->GetQname();
2079
				$cflink['description'] = $this->GetDescription();
2080
				$cflink['bandwidth'] = $this->GetBandwidth();
2081
				$cflink['bandwidthtype'] = $this->GetBwscale();
2082
				$cflink['enabled'] = $this->GetEnabled();
2083
				$cflink['default'] = $this->GetDefault();
2084
				$cflink['red'] = $this->GetRed();
2085
				$cflink['rio'] = $this->GetRio();
2086
				$cflink['ecn'] = $this->GetEcn();
2087
				$cflink['borrow'] = $this->GetBorrow();
2088
		}
2089
}
2090

    
2091

    
2092

    
2093

    
2094
/*
2095
 * XXX: TODO Make a class shaper to hide all these function
2096
 * from the global namespace.
2097
 */
2098

    
2099
/* 
2100
 * This is a layer violation but for now there is no way 
2101
 * i can find to properly do this with PHP.
2102
 */
2103
function altq_set_default_queue($interface, $value) {
2104
	global $altq_list_queues;
2105
		
2106
	$altq_tmp =& $altq_list_queues[$interface];
2107
	if ($altq_tmp) {
2108
		if ($value) {
2109
			$altq_tmp->SetDefaultQueuePresent("true");
2110
		}
2111
		else {
2112
			$altq_tmp->SetDefaultQueuePresent("false");
2113
		}
2114
	}
2115
}
2116

    
2117
function altq_get_default_queue($interface) {
2118
	global $altq_list_queues;
2119

    
2120
	$altq_tmp = $altq_list_queues[$interface];
2121
	if ($altq_tmp)  
2122
		return $altq_tmp->GetDefaultQueuePresent(); 
2123
}
2124

    
2125
function altq_check_default_queues() {
2126
	global $altq_list_queues;
2127

    
2128
	$count = 0;
2129
	if (is_array($altq_list_queues)) {
2130
		foreach($altq_list_queues as $altq) {
2131
			if ($altq->GetDefaultQueuePresent())
2132
				$count++;
2133
		}
2134
	}
2135
	else  $count++;;
2136
	
2137
	return 0;
2138
}
2139

    
2140
function &get_unique_queue_list() {
2141
	global $altq_list_queues;
2142
	
2143
	$qlist = array();
2144
	if (is_array($altq_list_queues)) {
2145
		foreach ($altq_list_queues as $altq) {
2146
			$tmplist =& $altq->get_queue_list();
2147
			foreach ($tmplist as $qname => $link)
2148
				$qlist[$qname] = $link;	
2149
		}
2150
	}
2151
	return $qlist;
2152
}
2153

    
2154
function get_is_ftp_queue($interface, $qname) {
2155
	global $config;
2156

    
2157
	if (isset($config['interfaces'][$interface]['ftpqueue']) &&
2158
		$config['interfaces'][$interface]['ftpqueue'] == $qname)
2159
		return true;
2160
	return false;
2161
}
2162

    
2163
function set_is_ftp_queue($interface, $qname) {
2164
	global $config;
2165

    
2166
	if (!is_array($config['interfaces'][$interface]['ftpqueue']))
2167
		$config['interfaces'][$interface]['ftpqueue'] = array();
2168
	$config['interfaces'][$interface]['ftpqueue'] = $qname;
2169
}
2170

    
2171
function ref_on_altq_queue_list($parent, $qname) {
2172
	if (isset($GLOBALS['queue_list'][$qname]))
2173
		$GLOBALS['queue_list'][$qname]++;
2174
	else
2175
		$GLOBALS['queue_list'][$qname] = 1;
2176

    
2177
	unref_on_altq_queue_list($parent);
2178
}
2179

    
2180
function unref_on_altq_queue_list($qname) {
2181
	$GLOBALS['queue_list'][$qname]--;
2182
	if ($GLOBALS['queue_list'][$qname] <= 1)
2183
		unset($GLOBALS['queue_list'][$qname]);	
2184
}
2185

    
2186
function read_altq_config() {
2187
	global $altq_list_queues, $config;
2188
	$path = array();
2189
	
2190
	$a_int = &$config['shaper']['queue'];
2191

    
2192
	$altq_list_queues = array();
2193
	
2194
	if (!is_array($config['shaper']['queue']))
2195
		return;
2196

    
2197
	foreach ($a_int as $key => $conf) {
2198
				$int = $conf['interface'];
2199
				$root =& new altq_root_queue();
2200
				$root->SetInterface($int);
2201
				$altq_list_queues[$root->GetInterface()] = &$root;
2202
				$root->ReadConfig($conf);
2203
		array_push($path, $key);
2204
		$root->SetLink($path);
2205
		if (is_array($conf['queue'])) {
2206
			foreach ($conf['queue'] as $key1 => $q) {
2207
				array_push($path, $key1);
2208
				/* 
2209
				 * XXX: we compeletely ignore errors here but anyway we must have 
2210
				 *	checked them before so no harm should be come from this.
2211
				 */
2212
				$root->add_queue($root->GetInterface(), $q, &$path, $input_errors);
2213
				array_pop($path);
2214
			} 	
2215
				}
2216
		array_pop($path);
2217
	}
2218
}
2219

    
2220

    
2221

    
2222
function get_interface_list_to_show() {
2223
	global $altq_list_queues, $config;
2224
		
2225
	$tree = "";
2226
	foreach ($config['interfaces'] as $if => $ifdesc) {
2227
		if ($altq_list_queues[$if]) {
2228
			continue;
2229
		} else  {
2230
			if (!is_altq_capable($ifdesc['if']))
2231
				continue;
2232
			if (!isset($ifdesc['enable']) && $if != "lan" && $if != "wan") 
2233
				continue;
2234
			$tree .= " <li><a href=\"firewall_shaper.php?interface=".$if."&action=add\">".$if."</a></li>";
2235
		}
2236
	}
2237
	
2238
	return $tree;
2239
}
2240

    
2241
function filter_generate_altq_queues() {
2242
	global $altq_list_queues;
2243
	
2244
	read_altq_config();
2245

    
2246
	$altq_rules = "";
2247
	foreach ($altq_list_queues as $altq) 
2248
		$altq_rules .= $altq->build_rules();
2249

    
2250
	return $altq_rules;
2251
}
2252

    
2253

    
2254
function build_iface_without_this_queue($iface, $qname) {
2255
	global $g, $altq_list_queues;
2256

    
2257
	$altq =& $altq_list_queues[$iface];
2258
				if ($altq)
2259
						$scheduler = ": " . $altq->GetScheduler();
2260
	$form = "<tr><td width=\"20%\" >";
2261
	$form .= "<a href=\"firewall_shaper.php?interface" . $iface . "&queue=" . $iface."&action=show\">".$iface.": ".$scheduler."</a>";
2262
		$form .= "</td></tr>";
2263
		$form .= "<tr><td width=\"100%\" class=\"vncellreq\">";
2264
		$form .= "<a href=\"firewall_shaper_queues.php?interface=";
2265
		$form .= $iface . "&queue=". $qname . "&action=add\">";
2266
		$form .= "<img src=\"";
2267
		$form .= "./themes/".$g['theme']."/images/icons/icon_plus.gif\"";
2268
		$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Clone shaper/queue on this interface\">";
2269
		$form .= " Clone shaper/queue on this interface</a></td></tr>";
2270

    
2271
		return $form;
2272

    
2273
}
2274

    
2275

    
2276
$default_shaper_msg =	"<tr><td align=\"center\" width=\"80%\" >";
2277
$default_shaper_msg .= "<span class=\"vexpl\"><strong><p><b>Welcome to the pfSense Traffic Shaper.</b><br />";
2278
$default_shaper_msg .= "The tree on the left helps you navigate through the queues <br />";
2279
$default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
2280
$default_shaper_ms .= " </p></strong></span>";
2281
$default_shaper_msg .= "</td></tr>";
2282

    
2283
?>
(20-20/29)