Project

General

Profile

Download (70.8 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, &$queue) {
314
		global $config;
315
		
316
		$mylink = &get_reference_to_me_in_config($this->GetLink());
317
		$link = &get_reference_to_me_in_config($queue->GetLink());
318
	
319
		if ($link && $mylink) {
320
				if (!is_array($mylink['queue'][$queue->GetQname()]))
321
						$mylink['queue'][$queue->GetQname()] = array();
322

    
323
				foreach ($link as $key => $value)
324
						$mylink['queue'][$queue->GetQname()][$key] = $value;
325
		}
326
	}
327

    
328

    
329
		function &get_queue_list($q = null) {
330
			$qlist = array();
331

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

    
340
		function &add_queue($interface, &$queue, &$path, &$input_errors) {
341

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

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

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

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

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

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

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

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

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

    
509
			return $javascript;
510
	}
511
	
512
	function build_shortform() {
513
			global $g;
514

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

    
535
			return $form;
536

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

    
612

    
613
		return $form;
614
	}
615

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

    
638
}
639

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

    
659
	/* This is here to help on form building and building rules/lists */
660
		var $subqueues = array();
661

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

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

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

    
800
		$mylink = &get_reference_to_me_in_config($this->GetLink());
801
		$link = &get_reference_to_me_in_config($queue->GetLink());
802

    
803
		if ($link && $mylink) {
804
				if (!is_array($mylink['queue'][$queue->GetQname()]))
805
						$mylink['queue'][$queue->GetQname()] = array();
806

    
807
				foreach ($link as $key => $value)
808
						$mylink['queue'][$queue->GetQname()][$key] = $value;
809
		}
810
	 }
811

    
812
	function clean_queue($sched) {
813
		clean_child_queues($sched, $this->GetLink());
814
		if (is_array($this->subqueues)) {
815
				foreach ($this->subqueues as $q)
816
						$q->clean_queue($sched);
817
				}
818
		}
819

    
820

    
821
		
822
        function &get_queue_list(&$qlist) {
823
                        $qlist[$this->GetQname()] = & $this;
824
                        if (is_array($this->subqueues)) {
825
                                foreach ($this->subqueues as $queue)
826
                                        $queue->get_queue_list($qlist);
827
                        }
828
        }
829

    
830
	function delete_queue() {
831
		unref_on_altq_queue_list($this->GetQname());
832
		if ($this->GetDefault())
833
				altq_set_default_queue($this->GetInterface(), "false");
834
		cleanup_queue_from_rules($this->GetQname());
835
		unset_object_by_reference($this->GetLink());
836
	}
837
	
838
	function delete_all() {
839
                if (count($this->subqueues)) {
840
                        foreach ($this->subqueues as $q) {
841
                                $q->delete_all();
842
                                unset_object_by_reference($q->GetLink());
843
                                unset($q);
844
                        }
845
                        unset($this->subqueues);
846
                }
847
        }
848

    
849
	 function &find_queue($interface, $qname) { 
850
		if ($qname == $this->GetQname())
851
			return $this; 
852
	}
853
	
854
	function find_parentqueue($interface, $qname) { return; }
855
		
856
	function validate_input($data, &$input_errors) {
857
	
858
		$reqfields[] = "name";
859
		$erqfieldsn[] = "Name";
860
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
861

    
862
		if ($data['priority'] && (!is_numeric($data['priority'])
863
						|| ($data['priority'] < 1) || ($data['priority'] > 15))) {
864
					$input_errors[] = "The priority must be an integer between 1 and 15.";
865
		}
866
		if ($data['qlimit'] && (!is_numeric($data['qlimit']))) 
867
				$input_errors[] = "Queue limit must be an integer";
868
		if ($data['qlimit'] < 0)
869
				$input_errors[] = "Queue limit must be positive";
870
		if (!preg_match("/^[a-zA-Z0-9_-]*$/", $data['name']))
871
			 $input_errors[] = "Queue names must be alphanumeric and _ or - only.";
872
		
873
	}
874

    
875
	function ReadConfig(&$q) {
876
		if (isset($q['name']))
877
				$this->SetQname($q['name']);
878
		if (isset($q['interface']))
879
				$this->SetInterface($q['interface']);
880
		if ($q['bandwidth'] <> "") {
881
			$this->SetBandwidth($q['bandwidth']);
882
			if ($q['bandwidthtype'] <> "")
883
				$this->SetBwscale($q['bandwidthtype']);
884
		}
885
		if (isset($q['qlimit']) && $q['qlimit'] <> "")
886
					$this->SetQlimit($q['qlimit']);
887
				if (isset($q['priority']))
888
						$this->SetQPriority($q['priority']);
889
				if (isset($q['description']) && $q['description'] != "")
890
						$this->SetDescription($q['description']);
891
		if (isset($q['ftpqueue']) && $q['ftpqueue'] <> "") 
892
			set_is_ftp_queue($this->GetInterface(), $this->GetQname());
893
		$this->SetRed($q['red']);
894
		$this->SetRio($q['rio']);
895
		$this->SetEcn($q['ecn']);
896
		$this->SetDefault($q['default']);
897
		$this->SetEnabled($q['enabled']);
898

    
899
		}
900

    
901
	function build_tree() {
902
			$tree = " <li><a href=\"firewall_shaper.php?interface=". $this->GetInterface()."&queue=". $this->GetQname()."&action=show"; 
903
			$tree .= "\" ";
904
			if ($this->GetDefault())
905
				$tree .= " class=\"navlnk\"";
906
			$tree .= " >" . $this->GetQname() . "</a>";
907
			/* 
908
			 * Not needed here!
909
			 * if (is_array($queues) {
910
			 *	  $tree .= "<ul>";
911
			 *	  foreach ($q as $queues) 
912
			 *		  $tree .= $queues['$q->GetName()']->build_tree();
913
			 *	  endforeach	
914
			 *	  $tree .= "</ul>";
915
			 * }
916
			 */
917

    
918
			$tree .= "</li>"; 
919

    
920
			return $tree;
921
		}
922
		
923
		/* Should return something like:
924
		 * queue $qname on $qinterface bandwidth ....
925
		 */
926
		function build_rules() {
927
				$pfq_rule = " queue ". $this->qname;
928
				if ($this->GetInterface())
929
						$pfq_rule .= " on ".convert_friendly_interface_to_real_interface_name($this->GetInterface());
930
				if ($this->GetQpriority())
931
						$pfq_rule .= " priority ".$this->GetQpriority();
932
				if ($this->GetQlimit())
933
						$pfq_rule .= " qlimit " . $this->GetQlimit();
934
				if ($this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetDefault()) {
935
						$pfq_rule .= " priq ( ";
936
					if ($this->GetRed()) {
937
						$comma = 1;
938
						$pfq_rule .= " red ";
939
					}
940
					if ($this->GetRio()) {
941
						if ($comma) 
942
								$pfq_rule .= " ,";
943
						$comma = 1;
944
						$pfq_rule .= " rio ";
945
					}
946
					if ($this->GetEcn()) {
947
						if ($comma) 
948
								$pfq_rule .= " ,";
949
						$comma = 1;
950
						$pfq_rule .= " ecn ";
951
					}	
952
					if ($this->GetDefault()) {
953
						if ($comma)
954
							$pfq_rule .= " ,";
955
						$pfq_rule .= " default ";
956
					}
957
					$pfq_rule .= " ) ";
958
				}
959
	
960
				$pfq_rule .= " \n";
961
		
962
				return $pfq_rule;
963
		}
964

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

    
1032
		return $form;
1033
		}
1034

    
1035
	function build_shortform() {
1036
		/* XXX: Hacks in site. Mostly layer violations!  */
1037
		global $g, $altq_list_queues;
1038

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

    
1069
	}
1070

    
1071
		function update_altq_queue_data(&$q) { 
1072
		$this->ReadConfig($q);
1073
	}
1074

    
1075
		function wconfig() {
1076
				$cflink =& get_reference_to_me_in_config($this->GetLink());
1077
		if (!is_array($cflink))
1078
			$cflink = array();
1079
		$cflink['name'] = $this->GetQname();
1080
				$cflink['interface'] = $this->GetInterface();
1081
				$cflink['qlimit'] = $this->GetQlimit();
1082
				$cflink['priority'] = $this->GetQpriority();
1083
		$cflink['description'] = $this->GetDescription();
1084
		$cflink['enabled'] = $this->GetEnabled();
1085
		$cflink['default'] = $this->GetDefault();
1086
		$cflink['red'] = $this->GetRed();
1087
		$cflink['rio'] = $this->GetRio();
1088
		$cflink['ecn'] = $this->GetEcn();
1089
	}
1090
}
1091

    
1092
class hfsc_queue extends priq_queue {
1093
		/* realtime */
1094
	var $realtime;
1095
		var $r_m1;
1096
		var $r_d;
1097
		var $r_m2;
1098
		/* linkshare */
1099
	var $linkshare;
1100
		var $l_m1;
1101
		var $l_d;
1102
		var $l_m2;
1103
		/* upperlimit */
1104
	var $upperlimit;
1105
		var $u_m1;
1106
		var $u_d;
1107
		var $u_m2;
1108

    
1109
		/*
1110
		 * HFSC can have nested queues.
1111
		 */
1112

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

    
1198

    
1199

    
1200
		function &add_queue($interface, &$qname, &$path, &$input_errors) {
1201

    
1202
			if (!is_array($this->subqueues))
1203
							$this->subqueues = array();
1204
			$q =& new hfsc_queue();
1205
			$q->SetInterface($this->GetInterface());
1206
			$q->SetParent(&$this);
1207
			$q->ReadConfig($qname);
1208
			$q->validate_input($qname, $input_errors);
1209
			if (count($input_errors)) {
1210
				return $q;
1211
			}
1212
			
1213
			$q->SetEnabled("on");
1214
			$q->SetLink($path);
1215
			switch ($q->GetBwscale()) {
1216
                        case "%":
1217
                                $myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
1218
                                break;
1219
                        default:
1220
                                $myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
1221
                                break;
1222
                	}
1223
                        $q->SetAvailableBandwidth($myBw);
1224
                        $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
1225

    
1226
			$this->subqueues[$q->GetQname()] =& $q; //new hfsc_queue()
1227
			ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
1228
			if (is_array($qname['queue'])) {
1229
				foreach ($qname['queue'] as $key1 => $que) {
1230
					array_push($path, $key1);
1231
								$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
1232
					array_pop($path);
1233
				}
1234
					}
1235
	
1236
			return $q;
1237
		}
1238

    
1239
		function delete_queue() { 
1240
			unref_on_altq_queue_list($this->GetQname());
1241
			if ($this->GetDefault()) 
1242
				altq_set_default_queue($this->GetInterface(), "false");
1243
			cleanup_queue_from_rules($this->GetQname());
1244
			$parent =& $this->GetParent();
1245
			foreach ($this->subqueues as $q)  {
1246
			$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
1247
				$q->delete_queue();
1248
			}
1249
			unset_object_by_reference($this->GetLink());
1250
			}
1251
	
1252
			/*
1253
			 * Should search even its childs
1254
			 */
1255
			function &find_queue($interface, $qname) {
1256
					if ($qname == $this->GetQname()) 
1257
							return $this;
1258
		
1259
					foreach ($this->subqueues as $q) {
1260
							$result =& $q->find_queue("", $qname);
1261
				if ($result)
1262
									return $result;
1263
					}
1264
			}
1265

    
1266
	function &find_parentqueue($interface, $qname) {
1267
		if ($this->subqueues[$qname]) 
1268
			return $this;
1269
				foreach ($this->subqueues as $q) {
1270
					$result = $q->find_parentqueue("", $qname);
1271
			if ($result)
1272
				return $result;
1273
		}
1274
		}
1275
	
1276
	function validate_input($data, &$input_errors) {
1277
		parent::validate_input($data, $input_errors);
1278
		
1279
		$reqfields[] = "bandwidth";
1280
		$reqdfieldsn[] = "Bandwidth";
1281
		$reqfields[] = "bandwidthtype";
1282
		$reqdfieldsn[] = "Bandwidthtype";
1283

    
1284
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
1285
		
1286
		if (isset($data['linkshare3']) && $data['linkshare3'] <> "") {
1287
		if ($data['bandwidth'] && (!is_numeric($data['bandwidth'])))
1288
                        $input_errors[] = "Bandwidth must be an integer.";
1289

    
1290
                if ($data['bandwidth'] < 0)
1291
                        $input_errors[] = "Bandwidth cannot be negative.";
1292

    
1293
                if ($data['bandwidthtype'] == "%") {
1294
                 if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
1295
                       $input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
1296
                 }
1297

    
1298
                $parent =& $this->GetParent();
1299
                switch ($data['bandwidthtype']) {
1300
                       case "%":
1301
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
1302
                       default:
1303
                             $mybw = floatval($data['bandwiddth']) * get_bandwidthtype_scale($data['bandwidthtype']);
1304
                             break;
1305
                }
1306
                if ($parent->GetAvailableBandwidth() < $myBw)
1307
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
1308
                if ($data['priority'] > 7)
1309
                        $input_errors[] = "Priority must be an integer between 1 and 7.";
1310
		}
1311

    
1312
		if ($data['upperlimit1'] <> "" &&  $data['upperlimit2'] == "")
1313
			$input_errors[] = ("upperlimit service curve defined but missing (d) value");
1314
		if ($data['upperlimit2'] <> "" &&  $data['upperlimit1'] == "")
1315
			$input_errors[] = ("upperlimit service curve defined but missing initial bandwidth (m1) value");
1316
		if ($data['upperlimit1'] <> "" && !is_valid_shaperbw($data['upperlimit1']))
1317
			$input_errors[] = ("upperlimit m1 value needs to be Kb, Mb, Gb, or %");
1318
		if ($data['upperlimit2'] <> "" && !is_numeric($data['upperlimit2']))
1319
			$input_errors[] = ("upperlimit d value needs to be numeric");
1320
		if ($data['upperlimit3'] <> "" && !is_valid_shaperbw($data['upperlimit3']))
1321
			$input_errors[] = ("upperlimit m2 value needs to be Kb, Mb, Gb, or %");
1322

    
1323
		if (isset($data['upperlimit']) && $data['upperlimit3'] <> "" && $data['upperlimit1'] <> "") {
1324
		$bw_1 = get_hfsc_bandwidth($this, $data['upperlimit1']);
1325
		$bw_2 = get_hfsc_bandwidth($this, $data['upperlimit3']);
1326
		if (floatval($bw_1) < floatval($bw_2)) 
1327
			$input_errors[] = ("upperlimit m1 cannot be smaller than m2");
1328

    
1329
		
1330
		if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1331
			$input_errors[] = ("upperlimit specification excedd 80% of allowable allocation.");
1332
		}
1333
		if ($data['linkshare1'] <> "" &&  $data['linkshare2'] == "")
1334
			$input_errors[] = ("linkshare service curve defined but missing (d) value");
1335
		if ($data['linkshare2'] <> "" &&  $data['linkshare1'] == "")
1336
			$input_errors[] = ("linkshare service curve defined but missing initial bandwidth (m1) value");
1337
		if ($data['linkshare1'] <> "" && !is_valid_shaperbw($data['linkshare1']))
1338
			$input_errors[] = ("linkshare m1 value needs to be Kb, Mb, Gb, or %");
1339
		if ($data['linkshare2'] <> "" && !is_numeric($data['linkshare2']))
1340
			$input_errors[] = ("linkshare d value needs to be numeric");
1341
		if ($data['linkshare3'] <> "" && !is_valid_shaperbw($data['linkshare3']))
1342
			$input_errors[] = ("linkshare m2 value needs to be Kb, Mb, Gb, or %");
1343
		if ($data['realtime1'] <> "" &&  $data['realtime2'] == "")
1344
			$input_errors[] = ("realtime service curve defined but missing (d) value");
1345
		if ($data['realtime2'] <> "" &&  $data['realtime1'] == "")
1346
			$input_errors[] = ("realtime service curve defined but missing initial bandwidth (m1) value");
1347

    
1348
		if (isset($data['linkshare']) && $data['linkshare3'] <> "" && $data['linkshare1'] <> "") {
1349
		$bw_1 = get_hfsc_bandwidth($this, $data['linkshare1']);
1350
                $bw_2 = get_hfsc_bandwidth($this, $data['linkshare3']);
1351
                if (floatval($bw_1) < floatval($bw_2))
1352
                        $input_errors[] = ("linkshare m1 cannot be smaller than m2");
1353

    
1354

    
1355
                if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1356
                        $input_errors[] = ("linkshare specification excedd 80% of allowable allocation.");
1357
		}
1358
		if ($data['realtime1'] <> "" && !is_valid_shaperbw($data['realtime1']))
1359
			$input_errors[] = ("realtime m1 value needs to be Kb, Mb, Gb, or %");
1360
		if ($data['realtime2'] <> "" && !is_numeric($data['realtime2']))
1361
			$input_errors[] = ("realtime d value needs to be numeric");
1362
		if ($data['realtime3'] <> "" && !is_valid_shaperbw($data['realtime3']))
1363
			$input_errors[] = ("realtime m2 value needs to be Kb, Mb, Gb, or %");
1364

    
1365
		if (isset($data['realtime']) && $data['realtime3'] <> "" && $data['realtime1'] <> "") {
1366
		$bw_1 = get_hfsc_bandwidth($this, $data['realtime1']);
1367
                $bw_2 = get_hfsc_bandwidth($this, $data['realtime3']);
1368
                if (floatval($bw_1) < floatval($bw_2))
1369
                        $input_errors[] = ("realtime m1 cannot be smaller than m2");
1370

    
1371

    
1372
                if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1373
                        $input_errors[] = ("realtime specification excedd 80% of allowable allocation.");
1374
		}
1375

    
1376
	}
1377

    
1378
		function ReadConfig(&$cflink) {
1379
		if (isset($cflink['linkshare']) && $cflink['linkshare'] <> "") {
1380
			if (isset($cflink['linkshare1']) && $cflink['linkshare1'] <> "") {
1381
				$this->SetL_m1($cflink['linkshare1']);
1382
                                $this->SetL_d($cflink['linkshare2']);
1383
				$this->SetLinkshare();
1384
			}
1385
			if (isset($cflink['linkshare3']) && $cflink['linkshare3'] <> "") {
1386
                                $this->SetL_m2($cflink['linkshare3']);
1387
				$this->SetLinkshare();
1388
			}
1389
		} else $this->DisableLinkshare();
1390
		if (isset($cflink['realtime']) && $cflink['realtime'] <> "") {
1391
                        if (isset($cflink['realtime1']) && $cflink['realtime1'] <> "") {
1392
                                $this->SetR_m1($cflink['realtime1']);
1393
                                $this->SetR_d($cflink['realtime2']);
1394
				$this->SetRealtime();
1395
			}
1396
                        if (isset($cflink['realtime3']) && $cflink['realtime3'] <> "") {
1397
                                $this->SetR_m2($cflink['realtime3']);
1398
				$this->SetRealtime();
1399
			}
1400
		} else $this->DisableRealtime(); 
1401
		if (isset($cflink['upperlimit']) && $cflink['upperlimit'] <> "") {
1402
                        if (isset($cflink['upperlimit1']) && $cflink['upperlimit1'] <> "") {
1403
                                $this->SetU_m1($cflink['upperlimit1']);
1404
                                $this->SetU_d($cflink['upperlimit2']);
1405
				$this->SetUpperlimit();
1406
			}
1407
                        if (isset($cflink['upperlimit3']) && $cflink['upperlimit3'] <> "") {
1408
                                $this->SetU_m2($cflink['upperlimit3']);
1409
				$this->SetUpperlimit();
1410
			}
1411
		} else $this->DisableUpperlimit();
1412
		parent::ReadConfig($cflink);
1413

    
1414
		}
1415

    
1416
	function build_tree() {
1417
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface() ."&queue=" . $this->GetQname()."&action=show"; 
1418
		$tree .= "\" ";
1419
		if ($this->GetDefault())
1420
								$tree .= " class=\"navlnk\"";
1421
		$tree .= " >" . $this->GetQname() . "</a>";
1422
		if (is_array($this->subqueues)) {
1423
			$tree .= "<ul>";
1424
			foreach ($this->subqueues as $q)  {
1425
				$tree .= $q->build_tree();
1426
			}	
1427
			$tree .= "</ul>";
1428
		}
1429
		$tree .= "</li>";
1430
		return $tree;
1431
	}
1432

    
1433
		/* Even this should take childs in consideration */
1434
		function build_rules() {
1435

    
1436
				$pfq_rule = " queue ". $this->qname;
1437
				if ($this->GetInterface())
1438
						$pfq_rule .= " on ".convert_friendly_interface_to_real_interface_name($this->GetInterface());
1439
		if ($this->GetBandwidth() && $this->GetBwscale())
1440
						$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
1441
					
1442
				if ($this->GetQpriority())
1443
						$pfq_rule .= " priority " . $this->GetQpriority();
1444
				if ($this->GetQlimit())
1445
						$pfq_rule .= " qlimit " . $this->GetQlimit();
1446
		  if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetRealtime() <> "" || $this->GetLinkshare() <> "" || $this->GetUpperlimit() <> "") {
1447
						$pfq_rule .= " hfsc ( ";
1448
						if ($this->GetRed()) {
1449
								$comma = 1;
1450
								$pfq_rule .= " red ";
1451
						}
1452
						if ($this->GetRio()) {
1453
								if ($comma) 
1454
										$pfq_rule .= " ,";
1455
								$comma = 1;
1456
								$pfq_rule .= " rio ";
1457
						}
1458
						if ($this->GetEcn()) {
1459
								if ($comma) 
1460
										$pfq_rule .= " ,";
1461
								$comma = 1;
1462
								$pfq_rule .= " ecn ";
1463
						}
1464
						if ($this->GetDefault()) {
1465
								if ($comma)
1466
										$pfq_rule .= " ,";
1467
								$comma = 1;
1468
								$pfq_rule .= " default ";
1469
						}
1470

    
1471
						if ($this->GetRealtime() <> "")  {
1472
				if ($comma) 
1473
									$pfq_rule .= " , ";
1474
				if ($this->GetR_m1()  <> "" && $this->GetR_d() <> "" && $this->GetR_m2() <> "")
1475
			$pfq_rule .= " realtime (".$this->GetR_m1() . ", " . $this->GetR_d().", ". $this->GetR_m2() .") ";
1476
				else  if ($this->GetR_m2() <> "")
1477
					$pfq_rule .= " realtime " . $this->GetR_m2();
1478
				$comma = 1;
1479
			}
1480
						if ($this->GetLinkshare() <> "") {
1481
								if ($comma)
1482
					$pfq_rule .= " ,";
1483
				if ($this->GetL_m1() <> "" && $this->GetL_d() <> "" && $this->GetL_m2() <> "")
1484
			$pfq_rule .= " linkshare (".$this->GetL_m1(). ", ". $this->GetL_d(). ", ". $this->GetL_m2(). ") ";
1485
				else if ($this->GetL_m2() <> "")
1486
					$pfq_rule .= " linkshare " . $this->GetL_m2() . " ";
1487
				$comma = 1;
1488
			}
1489
						if ($this->GetUpperlimit() <> "") {
1490
				if ($comma)
1491
					$pfq_rule .= " ,";
1492
				if ($this->GetU_m1() <> "" && $this->GetU_d() <> "" && $this->GetU_m2() <> "")
1493
							$pfq_rule .= " upperlimit (".$this->GetU_m1().", ". $this->GetU_d().", ". $this->GetU_m2(). ") ";
1494
				else if ($this->GetU_m2() <> "")
1495
					$pfq_rule .= " upperlimit " . $this->GetU_m2() . " ";
1496
			}
1497
					$pfq_rule .= " ) ";
1498
					}
1499
					if (count($this->subqueues)) {
1500
						$i = count($this->subqueues);
1501
						$pfq_rule .= " { ";
1502
						foreach ($this->subqueues as $qkey => $qnone) {
1503
								if ($i > 1) {
1504
										$i--;
1505
										$pfq_rule .= " {$qkey}, ";
1506
								} else
1507
										$pfq_rule .= " {$qkey} ";
1508
								$pfq_rule .= " } \n";
1509
								foreach ($this->subqueues as $q)
1510
									$pfq_rule .= $q->build_rules();
1511
						}
1512
					}
1513

    
1514
				 $pfq_rule .= " \n";
1515
			
1516
				return $pfq_rule;
1517
		}
1518

    
1519
	function build_javascript() {
1520
		$javascript = parent::build_javascript();
1521
		$javascript .= "<script type=\"text/javascript\">";
1522
		$javascript .= "function enable_realtime(enable_over) { \n";
1523
		$javascript .= "if (document.iform.realtime.checked || enable_over) { \n";
1524
		$javascript .= "document.iform.realtime1.disabled = 0;\n";
1525
		$javascript .= "document.iform.realtime2.disabled = 0;\n";
1526
		$javascript .= "document.iform.realtime3.disabled = 0;\n";
1527
		$javascript .= " } else { \n";
1528
		$javascript .= "document.iform.realtime1.disabled = 1;\n";
1529
		$javascript .= "document.iform.realtime2.disabled = 1;\n";
1530
		$javascript .= "document.iform.realtime3.disabled = 1;\n";
1531
		$javascript .= " } \n";
1532
		$javascript .= " } \n";
1533
		$javascript .= "function enable_linkshare(enable_over) { \n";
1534
		$javascript .= "if (document.iform.linkshare.checked || enable_over) { \n";
1535
		$javascript .= "document.iform.linkshare1.disabled = 0;\n";
1536
		$javascript .= "document.iform.linkshare2.disabled = 0;\n";
1537
		$javascript .= "document.iform.linkshare3.disabled = 0;\n";
1538
		$javascript .= " } else { \n";
1539
		$javascript .= "document.iform.linkshare1.disabled = 1;\n";
1540
		$javascript .= "document.iform.linkshare2.disabled = 1;\n";
1541
		$javascript .= "document.iform.linkshare3.disabled = 1;\n";
1542
		$javascript .= " } \n";
1543
		$javascript .= " } \n";
1544
		$javascript .= "function enable_upperlimit(enable_over) { \n";
1545
		$javascript .= "if (document.iform.upperlimit.checked || enable_over) { \n";
1546
		$javascript .= "document.iform.upperlimit1.disabled = 0;\n";
1547
		$javascript .= "document.iform.upperlimit2.disabled = 0;\n";
1548
		$javascript .= "document.iform.upperlimit3.disabled = 0;\n";
1549
		$javascript .= " } else { \n";
1550
		$javascript .= "document.iform.upperlimit1.disabled = 1;\n";
1551
		$javascript .= "document.iform.upperlimit2.disabled = 1;\n";
1552
		$javascript .= "document.iform.upperlimit3.disabled = 1;\n";
1553
		$javascript .= " } \n";
1554
			
1555
		$javascript .= "} \n";
1556
		$javascript .= "</script>";
1557

    
1558
		return $javascript;
1559
	}
1560

    
1561
		function build_form() {
1562
				$form = "<tr>";
1563
				$form .= "<td valign=\"top\" class=\"vncellreq\">Bandwidth</td>";
1564
				$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
1565
				$form .= htmlspecialchars($this->GetBandwidth());
1566
				$form .= "\">";
1567
				$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
1568
				$form .= "<option value=\"Gb\"";
1569
				if ($this->GetBwscale() == "Gb")
1570
						$form .= " selected=\"yes\"";
1571
				$form .= ">Gbit/s</option>";
1572
				$form .= "<option value=\"Mb\"";
1573
				if ($this->GetBwscale() == "Mb")
1574
						$form .= " selected=\"yes\"";
1575
				$form .= ">Mbit/s</option>";
1576
				$form .= "<option value=\"Kb\"";
1577
				if ($this->GetBwscale() == "Kb")
1578
						$form .= " selected=\"yes\"";
1579
				$form .= ">Kbit/s</option>";
1580
				$form .= "<option value=\"\"";
1581
				if ($this->GetBwscale() == "b")
1582
						$form .= " selected=\"yes\"";
1583
				$form .= ">Bit/s</option>";
1584
				$form .= "<option value=\"%\"";
1585
				if ($this->GetBwscale() == "%")
1586
						$form .= " selected=\"yes\"";
1587
				$form .= ">%</option>";
1588
				$form .= "</select> <br>";
1589
				$form .= "<span class=\"vexpl\">Choose the amount of bandwidth for this queue";
1590
				$form .= "</span></td>";
1591
				$form .= parent::build_form();
1592
				$form .= "<tr>";
1593
				$form .= "<td width=\"22%\" valign=\"top\" class=\"vncellreq\">Service Curve (sc)</td>";
1594
				$form .= "<td width=\"78%\" class=\"vtable\">";
1595
				$form .= "<table>";
1596
				$form .= "<tr><td>&nbsp;</td><td><center>m1</center></td><td><center>d</center></td><td><center><b>m2</b></center></td></tr>";
1597
				$form .= "<tr><td><input type=\"checkbox\" id=\"upperlimit\" name=\"upperlimit\"";
1598
				if($this->GetUpperlimit()<> "") 
1599
					$form .=  " CHECKED ";
1600
				$form .= "onChange=\"enable_upperlimit()\"> Upperlimit:</td><td><input size=\"6\" value=\"";
1601
				$form .= htmlspecialchars($this->GetU_m1());
1602
				$form .= "\" id=\"upperlimit1\" name=\"upperlimit1\" ";
1603
				if ($this->GetUpperlimit() == "") $form .= " disabled";
1604
				$form .= "></td><td><input size=\"6\" value=\"";
1605
				$form .= htmlspecialchars($this->GetU_d());
1606
				$form .= "\" id=\"upperlimi2\" name=\"upperlimit2\" ";
1607
		if ($this->GetUpperlimit() == "") $form .= " disabled";
1608
		$form .= "></td><td><input size=\"6\" value=\"";
1609
				$form .= htmlspecialchars($this->GetU_m2());
1610
				$form .= "\" id=\"upperlimit3\" name=\"upperlimit3\" ";
1611
		if ($this->GetUpperlimit() == "") $form .= " disabled";
1612
		$form .= "></td><td>The maximum allowed bandwidth for the queue.</td></tr>";
1613
				$form .= "<tr><td><input type=\"checkbox\" id=\"realtime\" name=\"realtime\"";
1614
				if($this->GetRealtime() <> "") 
1615
			$form .=  " CHECKED ";
1616
				$form .= "onChange=\"enable_realtime()\"> Real time:</td><td><input size=\"6\" value=\"";
1617
				$form .= htmlspecialchars($this->GetR_m1());
1618
				$form .= "\" id=\"realtime1\" name=\"realtime1\" ";
1619
		if ($this->GetRealtime() == "") $form .= " disabled";
1620
		$form .= "></td><td><input size=\"6\" value=\"";
1621
				$form .= htmlspecialchars($this->GetR_d());
1622
				$form .= "\" id=\"realtime2\" name=\"realtime2\" ";
1623
		if ($this->GetRealtime() == "") $form .= " disabled";
1624
		$form .= "></td><td><input size=\"6\" value=\"";
1625
				$form .= htmlspecialchars($this->GetR_m2());
1626
				$form .= "\" id=\"realtime3\" name=\"realtime3\" ";
1627
		if ($this->GetRealtime() == "") $form .= " disabled";
1628
		$form .= "></td><td>The minimum required bandwidth for the queue.</td></tr>";
1629
				$form .= "<tr><td><input type=\"checkbox\" id=\"linkshare\" id=\"linkshare\" name=\"linkshare\"";
1630
				if($this->GetLinkshare() <> "") 
1631
			$form .=  " CHECKED ";
1632
				$form .= "onChange=\"enable_linkshare()\"> Link share:</td><td><input size=\"6\" value=\"";
1633
				$form .= htmlspecialchars($this->GetL_m1());
1634
				$form .= "\" id=\"linkshare1\" name=\"linkshare1\" ";
1635
		if ($this->GetLinkshare() == "") $form .= " disabled";
1636
		$form .= "></td><td><input size=\"6\" value=\"";
1637
				$form .= htmlspecialchars($this->GetL_d());
1638
				$form .= "\" id=\"linkshare2\" name=\"linkshare2\" ";
1639
		if ($this->GetLinkshare() == "") $form .= " disabled";
1640
		$form .= "></td><td><input size=\"6\" value=\"";
1641
				$form .= htmlspecialchars($this->GetL_m2());
1642
				$form .= "\" id=\"linkshare3\" name=\"linkshare3\" ";
1643
		if ($this->GetLinkshare() == "") $form .= " disabled";
1644
		$form .= "></td><td>The bandwidth share of a backlogged queue - this overrides priority.</td></tr>";
1645
				$form .= "</table><br>";
1646
				$form .= "The format for service curve specifications is (m1, d, m2).  m2 controls";
1647
				$form .= "the bandwidth assigned to the queue.  m1 and d are optional and can be";
1648
				$form .= "used to control the initial bandwidth assignment.  For the first d milliseconds the queue gets the bandwidth given as m1, afterwards the value";
1649
				$form .= "given in m2.";
1650
				$form .= "</span></td>";
1651
				$form .= "</tr>";
1652

    
1653
				return $form;
1654
		}
1655

    
1656
	function update_altq_queue_data(&$data) { 
1657
		$this->ReadConfig($data);
1658
	}
1659

    
1660
	function wconfig() {
1661
		$cflink =& get_reference_to_me_in_config($this->GetLink());
1662
		if (!is_array($cflink))
1663
			$cflink = array();
1664
			$cflink['name'] = $this->GetQname();
1665
			$cflink['interface'] = $this->GetInterface();
1666
			$cflink['qlimit'] = $this->GetQlimit();
1667
			$cflink['priority'] = $this->GetQpriority();
1668
			$cflink['description'] = $this->GetDescription();
1669
			$cflink['bandwidth'] = $this->GetBandwidth();
1670
			$cflink['bandwidthtype'] = $this->GetBwscale();
1671
			$cflink['enabled'] = $this->GetEnabled();
1672
			$cflink['default'] = $this->GetDefault();
1673
			$cflink['red'] = $this->GetRed();
1674
			$cflink['rio'] = $this->GetRio();
1675
			$cflink['ecn'] = $this->GetEcn();
1676
			if ($this->GetLinkshare() <> "") {
1677
				if ($this->GetL_m1() <> "") {
1678
					$cflink['linkshare1'] = $this->GetL_m1();
1679
					$cflink['linkshare2'] = $this->GetL_d();
1680
					$cflink['linkshare'] = "on";
1681
				}
1682
				if ($this->GetL_m2() <> "") {
1683
					$cflink['linkshare3'] = $this->GetL_m2();
1684
					$cflink['linkshare'] = "on";
1685
				}
1686
			} else $cflink['linkshare'] = "";
1687
			if ($this->GetRealtime() <> "") {
1688
				if ($this->GetR_m1() <> "") {
1689
					$cflink['realtime1'] = $this->GetR_m1();
1690
					$cflink['realtime2'] = $this->GetR_d();
1691
					$cflink['realtime'] = "on";
1692
				}
1693
				if ($this->GetR_m2() <> "") {
1694
					$cflink['realtime3'] = $this->GetR_m2();
1695
					$cflink['realtime'] = "on";
1696
				}
1697
			} else $cflink['realtime'] = "";
1698
			if ($this->GetUpperlimit() <> "") {
1699
				if ($this->GetU_m1() <> "") {
1700
					$cflink['upperlimit1'] = $this->GetU_m1();
1701
					$cflink['upperlimit2'] = $this->GetU_d();
1702
					$cflink['upperlimit'] = "on";
1703
				}
1704
				if ($this->GetU_m2() <> "") {
1705
					$cflink['upperlimit3'] = $this->GetU_m2();
1706
					$cflink['upperlimit'] = "on";
1707
				}
1708
			} else $cflink['upperlimit'] = "";
1709
		}
1710
	}
1711

    
1712
class cbq_queue extends priq_queue {
1713
		var $qborrow;
1714

    
1715
	function GetBorrow() {
1716
		return $this->qborrow;
1717
	}
1718
	function SetBorrow($borrow) {
1719
		$this->qborrow = $borrow;
1720
	}
1721
	function CanHaveChilds() {
1722
			return true;
1723
	}
1724

    
1725
	function &add_queue($interface, &$qname, &$path, &$input_errors) {
1726

    
1727
		if (!is_array($this->subqueues))
1728
						$this->subqueues = array();
1729
		$q =& new cbq_queue();
1730
		$q->SetInterface($this->GetInterface());
1731
		$q->SetParent(&$this);
1732
		$q->ReadConfig($qname);
1733
                $q->validate_input($qname, $input_errors);
1734
                if (count($input_errors)) {
1735
                        return $q;
1736
                }
1737
                switch ($q->GetBwscale()) {
1738
                        case "%":
1739
                                $myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
1740
                                break;
1741
                        default:
1742
                                $myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
1743
                                break;
1744
                }
1745
                $q->SetAvailableBandwidth($myBw);
1746
                $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
1747

    
1748
		$q->SetEnabled("on");
1749
		$q->SetLink($path);
1750
		$this->subqueues[$q->GetQName()] = &$q;
1751
		ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
1752
		if (is_array($qname['queue'])) {
1753
				foreach ($qname['queue'] as $key1 => $que) {
1754
						array_push($path, $key1);
1755
						$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
1756
						array_pop($path);
1757
				}
1758
		}
1759

    
1760
		return $q;
1761
		}
1762
	
1763
		/*
1764
		 * Should search even its childs
1765
		 */
1766
		function &find_queue($interface, $qname) {
1767
				if ($qname == $this->GetQname())
1768
						return $this;
1769
				foreach ($this->subqueues as $q) {
1770
						$result =& $q->find_queue("", $qname);
1771
			if ($result)
1772
								return $result;
1773
				}
1774
		}
1775

    
1776
	function &find_parentqueue($interface, $qname) {
1777
				if ($this->subqueues[$qname])
1778
						return $this;
1779
				foreach ($this->subqueues as $q) {
1780
					$result = $q->find_parentqueue("", $qname);
1781
			if ($result)
1782
				return $result;
1783
		}
1784
		}
1785

    
1786
		function delete_queue() {
1787
			unref_on_altq_queue_list($this->GetQname());
1788
			if ($this->GetDefault())
1789
				altq_set_default_queue($this->GetInterface(), "false");
1790
			cleanup_queue_from_rules($this->GetQname());
1791
			foreach ($this->subqueues as $q) {
1792
			$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
1793
				$q->delete_queue();
1794
			}
1795
			unset_object_by_reference($this->GetLink());
1796
		}
1797
	
1798
	function validate_input($data, &$input_errors) {
1799
		parent::validate_input($data, $input_errors);
1800
		
1801
		if ($data['priority'] > 7)
1802
				$input_errors[] = "Priority must be an integer between 1 and 7.";
1803
		$reqfields[] = "bandwidth";
1804
		$reqdfieldsn[] = "Bandwidth";
1805
		$reqfields[] = "bandwidthtype";
1806
		$reqdfieldsn[] = "Bandwidthtype";
1807

    
1808
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
1809
		
1810
		if ($data['bandwidth'] && !is_numeric($data['bandwidth']))
1811
                 $input_errors[] = "Bandwidth must be an integer.";
1812

    
1813

    
1814
           if ($data['bandwidth'] < 0)
1815
                       $input_errors[] = "Bandwidth cannot be negative.";
1816

    
1817

    
1818
           if ($data['bandwidthtype'] == "%") {
1819
                 if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
1820
                       $input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
1821
           }
1822

    
1823
           $parent =& $this->GetParent();
1824
           switch ($data['bandwidthtype']) {
1825
                       case "%":
1826
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
1827
                       default:
1828
                             $mybw = floatval($data['bandwiddth']) * get_bandwidthtype_scale($data['bandwidthtype']);
1829
                             break;
1830
           }
1831
                if ($parent->GetAvailableBandwidth() < floatval($myBw))
1832
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
1833
	}
1834
		function ReadConfig(&$q) {
1835
				parent::ReadConfig($q);
1836
		if ($q['borrow'])
1837
			$this->SetBorrow("on");
1838
		}
1839
		
1840
	function build_javascript() {
1841
		return parent::build_javascript();
1842
	}
1843

    
1844
	function build_tree() {
1845
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface()."&queue=" . $this->GetQname()."&action=show"; 
1846
			$tree .= "\" ";
1847
			if ($this->GetDefault())
1848
								$tree .= " class=\"navlnk\"";
1849
			$tree .= " >" . $this->GetQname() . "</a>";
1850
			if (is_array($this->subqueues)) {
1851
				$tree .= "<ul>";
1852
				foreach ($this->subqueues as $q)  {
1853
					$tree .= $q->build_tree();
1854
				}	
1855
				$tree .= "</ul>";
1856
			}
1857
			$tree .= "</li>";
1858
			return $tree;
1859
	}
1860
		
1861
	/* Even this should take childs in consideration */
1862
	function build_rules() {
1863
		   $pfq_rule = "queue ". $this->qname;
1864
			if ($this->GetInterface())
1865
					$pfq_rule .= " on ".convert_friendly_interface_to_real_interface_name($this->GetInterface());
1866
			if ($this->GetBandwidth() && $this->GetBwscale())
1867
					$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
1868
			if ($this->GetQpriority())
1869
					$pfq_rule .= " priority " . $this->GetQpriority();
1870
			if ($this->GetQlimit())
1871
					$pfq_rule .= " qlimit " . $this->GetQlimit();
1872
			if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetBorrow()) {
1873
				$pfq_rule .= " cbq ( ";
1874
				if ($this->GetRed()) {
1875
						$comma = 1;
1876
						$pfq_rule .= " red ";
1877
				}
1878
				if ($this->GetRio()) {
1879
						if ($comma) 
1880
								$pfq_rule .= " ,";
1881
						$comma = 1;
1882
						$pfq_rule .= " rio ";
1883
				}
1884
				if ($this->GetEcn()) {
1885
						if ($comma) 
1886
								$pfq_rule .= " ,";
1887
						$comma = 1;
1888
						$pfq_rule .= " ecn ";
1889
				}
1890
				if ($this->GetDefault()) {
1891
						if ($comma)
1892
								$pfq_rule .= " ,";
1893
						$comma = 1;
1894
						$pfq_rule .= " default ";
1895
				}
1896
				if ($this->GetBorrow()) {
1897
					if ($comma)
1898
						$pfq_rule .= ", ";
1899
					$pfq_rule .= " borrow ";
1900
				}
1901
				$pfq_rule .= " ) ";
1902
			} 
1903
			if (count($this->subqueues)) {
1904
					$i = count($this->subqueues);
1905
					$pfq_rule .= " { ";
1906
					foreach ($this->subqueues as $qkey => $qnone) {
1907
							if ($i > 1) {
1908
									$i--;
1909
									$pfq_rule .= " {$qkey}, ";
1910
							} else
1911
									$pfq_rule .= " {$qkey} ";
1912
					}
1913
					$pfq_rule .= " } \n";
1914
					foreach ($this->subqueues as $q)
1915
							$pfq_rule .= $q->build_rules();
1916
			}
1917

    
1918
			$pfq_rule .= " \n";
1919
			return $pfq_rule;
1920
	}
1921

    
1922
	function build_form() {
1923
		$form = "<tr>";
1924
		$form .= "<td valign=\"top\" class=\"vncellreq\">Bandwidth</td>";
1925
		$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
1926
		if ($this->GetBandwidth() > 0)
1927
				$form .= htmlspecialchars($this->GetBandwidth());
1928
		$form .= "\">";
1929
		$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
1930
		$form .= "<option value=\"Gb\"";
1931
		if ($this->GetBwscale() == "Gb")
1932
				$form .= " selected=\"yes\"";
1933
		$form .= ">Gbit/s</option>";
1934
		$form .= "<option value=\"Mb\"";
1935
		if ($this->GetBwscale() == "Mb")
1936
				$form .= " selected=\"yes\"";
1937
		$form .= ">Mbit/s</option>";
1938
		$form .= "<option value=\"Kb\"";
1939
		if ($this->GetBwscale() == "Kb")
1940
				$form .= " selected=\"yes\"";
1941
		$form .= ">Kbit/s</option>";
1942
		$form .= "<option value=\"\"";
1943
		if ($this->GetBwscale() == "b")
1944
				$form .= " selected=\"yes\"";
1945
		$form .= ">Bit/s</option>";
1946
		$form .= "<option value=\"%\"";
1947
		if ($this->GetBwscale() == "%")
1948
				$form .= " selected=\"yes\"";
1949
		$form .= ">%</option>";
1950
		$form .= "</select> <br>";
1951
		$form .= "<span class=\"vexpl\">Choose the amount of bandwidth for this queue";
1952
		$form .= "</span></td></tr>";
1953
		$form .= parent::build_form();
1954
		$form .= "<tr><td class=\"vncellreq\">Scheduler specific options</td>";
1955
		$form .= "<td class=\"vtable\"><input type=\"checkbox\" id=\"borrow\" name=\"borrow\"";
1956
			if($this->GetBorrow() == "on") 
1957
		$form .=  " CHECKED ";
1958
		$form .= "> Borrow from other queues when available<br></td></tr>";
1959

    
1960
		return $form;
1961
	}
1962

    
1963
	function update_altq_queue_data(&$data) { 
1964
		$this->ReadConfig($data);
1965
	}
1966

    
1967
	function wconfig() {
1968
		$cflink =& get_reference_to_me_in_config($this->GetLink());
1969
				if (!is_array($cflink))
1970
						$cflink = array();
1971
				$cflink['interface'] = $this->GetInterface();
1972
				$cflink['qlimit'] = $this->GetQlimit();
1973
				$cflink['priority'] = $this->GetQpriority();
1974
				$cflink['name'] = $this->GetQname();
1975
				$cflink['description'] = $this->GetDescription();
1976
				$cflink['bandwidth'] = $this->GetBandwidth();
1977
				$cflink['bandwidthtype'] = $this->GetBwscale();
1978
				$cflink['enabled'] = $this->GetEnabled();
1979
				$cflink['default'] = $this->GetDefault();
1980
				$cflink['red'] = $this->GetRed();
1981
				$cflink['rio'] = $this->GetRio();
1982
				$cflink['ecn'] = $this->GetEcn();
1983
				$cflink['borrow'] = $this->GetBorrow();
1984
		}
1985
}
1986

    
1987

    
1988

    
1989

    
1990
/*
1991
 * XXX: TODO Make a class shaper to hide all these function
1992
 * from the global namespace.
1993
 */
1994

    
1995
/* 
1996
 * This is a layer violation but for now there is no way 
1997
 * i can find to properly do this with PHP.
1998
 */
1999
function altq_set_default_queue($interface, $value) {
2000
	global $altq_list_queues;
2001
		
2002
	$altq_tmp =& $altq_list_queues[$interface];
2003
	if ($altq_tmp) {
2004
		if ($value) {
2005
			$altq_tmp->SetDefaultQueuePresent("true");
2006
		}
2007
		else {
2008
			$altq_tmp->SetDefaultQueuePresent("false");
2009
		}
2010
	}
2011
}
2012

    
2013
function altq_get_default_queue($interface) {
2014
	global $altq_list_queues;
2015

    
2016
	$altq_tmp = $altq_list_queues[$interface];
2017
	if ($altq_tmp)  
2018
		return $altq_tmp->GetDefaultQueuePresent(); 
2019
}
2020

    
2021
function altq_check_default_queues() {
2022
	global $altq_list_queues;
2023

    
2024
	$count = 0;
2025
	if (is_array($altq_list_queues)) {
2026
		foreach($altq_list_queues as $altq) {
2027
			if ($altq->GetDefaultQueuePresent())
2028
				$count++;
2029
		}
2030
	}
2031
	else  $count++;;
2032
	
2033
	return 0;
2034
}
2035

    
2036
function &get_unique_queue_list() {
2037
	global $altq_list_queues;
2038
	
2039
	$qlist = array();
2040
	if (is_array($altq_list_queues)) {
2041
		foreach ($altq_list_queues as $altq) {
2042
			$tmplist =& $altq->get_queue_list();
2043
			foreach ($tmplist as $qname => $link)
2044
				$qlist[$qname] = $link;	
2045
		}
2046
	}
2047
	return $qlist;
2048
}
2049

    
2050
function get_is_ftp_queue($interface, $qname) {
2051
	global $config;
2052

    
2053
	if (isset($config['interfaces'][$interface]['ftpqueue']) &&
2054
		$config['interfaces'][$interface]['ftpqueue'] == $qname)
2055
		return true;
2056
	return false;
2057
}
2058

    
2059
function set_is_ftp_queue($interface, $qname) {
2060
	global $config;
2061

    
2062
	if (!is_array($config['interfaces'][$interface]['ftpqueue']))
2063
		$config['interfaces'][$interface]['ftpqueue'] = array();
2064
	$config['interfaces'][$interface]['ftpqueue'] = $qname;
2065
}
2066

    
2067
function ref_on_altq_queue_list($parent, $qname) {
2068
	if (isset($GLOBALS['queue_list'][$qname]))
2069
		$GLOBALS['queue_list'][$qname]++;
2070
	else
2071
		$GLOBALS['queue_list'][$qname] = 1;
2072

    
2073
	unref_on_altq_queue_list($parent);
2074
}
2075

    
2076
function unref_on_altq_queue_list($qname) {
2077
	$GLOBALS['queue_list'][$qname]--;
2078
	if ($GLOBALS['queue_list'][$qname] <= 1)
2079
		unset($GLOBALS['queue_list'][$qname]);	
2080
}
2081

    
2082
function read_altq_config() {
2083
	global $altq_list_queues, $config;
2084
	$path = array();
2085
	
2086
	$a_int = &$config['shaper']['queue'];
2087

    
2088
	$altq_list_queues = array();
2089
	
2090
	if (!is_array($config['shaper']['queue']))
2091
		return;
2092

    
2093
	foreach ($a_int as $key => $conf) {
2094
				$int = $conf['interface'];
2095
				$root =& new altq_root_queue();
2096
				$root->SetInterface($int);
2097
				$altq_list_queues[$root->GetInterface()] = &$root;
2098
				$root->ReadConfig($conf);
2099
		array_push($path, $key);
2100
		$root->SetLink($path);
2101
		if (is_array($conf['queue'])) {
2102
			foreach ($conf['queue'] as $key1 => $q) {
2103
				array_push($path, $key1);
2104
				/* 
2105
				 * XXX: we compeletely ignore errors here but anyway we must have 
2106
				 *	checked them before so no harm should be come from this.
2107
				 */
2108
				$root->add_queue($root->GetInterface(), $q, &$path, $input_errors);
2109
				array_pop($path);
2110
			} 	
2111
				}
2112
		array_pop($path);
2113
	}
2114
}
2115

    
2116

    
2117

    
2118
function get_interface_list_to_show() {
2119
	global $altq_list_queues, $config;
2120
		
2121
	$tree = "";
2122
	foreach ($config['interfaces'] as $if => $ifdesc) {
2123
		if ($altq_list_queues[$if])
2124
			continue;
2125
		else  {
2126
			if (!is_altq_capable($ifdesc['if'])) 
2127
				continue;
2128
			if (!isset($ifdesc['enable']) && $if != "lan" && $if != "wan")
2129
				continue;
2130
			$tree .= " <li><a href=\"firewall_shaper.php?interface=".$if."&action=add\">".$if."</a></li>";
2131
		}
2132
	}
2133
	
2134
	return $tree;
2135
}
2136

    
2137
function filter_generate_altq_queues() {
2138
	global $altq_list_queues;
2139
	
2140
	read_altq_config();
2141

    
2142
	$altq_rules = "";
2143
	foreach ($altq_list_queues as $altq) 
2144
		$altq_rules .= $altq->build_rules();
2145

    
2146
	return $altq_rules;
2147
}
2148

    
2149

    
2150
function build_iface_without_this_queue($iface, $qname) {
2151
	global $g, $altq_list_queues;
2152

    
2153
	$altq =& $altq_list_queues[$iface];
2154
				if ($altq)
2155
						$scheduler = ": " . $altq->GetScheduler();
2156
	$form = "<tr><td width=\"20%\" >";
2157
	$form .= "<a href=\"firewall_shaper.php?interface" . $iface . "&queue=" . $iface."&action=show\">".$iface.": ".$scheduler."</a>";
2158
		$form .= "</td></tr>";
2159
		$form .= "<tr><td width=\"100%\" class=\"vncellreq\">";
2160
		$form .= "<a href=\"firewall_shaper_queues.php?interface=";
2161
		$form .= $iface . "&queue=". $qname . "&action=add\">";
2162
		$form .= "<img src=\"";
2163
		$form .= "./themes/".$g['theme']."/images/icons/icon_plus.gif\"";
2164
		$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Clone shaper/queue on this interface\">";
2165
		$form .= " Clone shaper/queue on this interface</a></td></tr>";
2166

    
2167
		return $form;
2168

    
2169
}
2170

    
2171

    
2172
$default_shaper_msg =	"<tr><td align=\"center\" width=\"80%\" >";
2173
$default_shaper_msg .= "<span class=\"vexpl\"><strong><p><b>Welcome to the pfSense Traffic Shaper.</b><br />";
2174
$default_shaper_msg .= "The tree on the left helps you navigate through the queues <br />";
2175
$default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
2176
$default_shaper_ms .= " </p></strong></span>";
2177
$default_shaper_msg .= "</td></tr>";
2178

    
2179
?>
(20-20/29)