Project

General

Profile

Download (11.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * firewall_shaper.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright notice,
13
 *    this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this software
21
 *    must display the following acknowledgment:
22
 *    "This product includes software developed by the pfSense Project
23
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
24
 *
25
 * 4. The names "pfSense" and "pfSense Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    coreteam@pfsense.org.
29
 *
30
 * 5. Products derived from this software may not be called "pfSense"
31
 *    nor may "pfSense" appear in their names without prior written
32
 *    permission of the Electric Sheep Fencing, LLC.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *
37
 * "This product includes software developed by the pfSense Project
38
 * for use in the pfSense software distribution (http://www.pfsense.org/).
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
41
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
44
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51
 * OF THE POSSIBILITY OF SUCH DAMAGE.
52
 */
53

    
54
##|+PRIV
55
##|*IDENT=page-firewall-trafficshaper
56
##|*NAME=Firewall: Traffic Shaper
57
##|*DESCR=Allow access to the 'Firewall: Traffic Shaper' page.
58
##|*MATCH=firewall_shaper.php*
59
##|-PRIV
60

    
61
require_once("guiconfig.inc");
62
require_once("functions.inc");
63
require_once("filter.inc");
64
require_once("shaper.inc");
65
require_once("rrd.inc");
66

    
67
if ($_GET['reset'] != "") {
68
	/* XXX: Huh, why are we killing php? */
69
	mwexec("killall -9 pfctl php");
70
	exit;
71
}
72

    
73
$pgtitle = array(gettext("Firewall"), gettext("Traffic Shaper"), gettext("By Interface"));
74
$shortcut_section = "trafficshaper";
75

    
76
$shaperIFlist = get_configured_interface_with_descr();
77
read_altq_config();
78
/*
79
 * The whole logic in these code maybe can be specified.
80
 * If you find a better way contact me :).
81
 */
82

    
83
if ($_GET) {
84
	if ($_GET['queue']) {
85
		$qname = htmlspecialchars(trim($_GET['queue']));
86
	}
87
	if ($_GET['interface']) {
88
		$interface = htmlspecialchars(trim($_GET['interface']));
89
	}
90
	if ($_GET['action']) {
91
		$action = htmlspecialchars($_GET['action']);
92
	}
93
}
94

    
95
if ($_POST) {
96
	if ($_POST['name']) {
97
		$qname = htmlspecialchars(trim($_POST['name']));
98
	}
99
	if ($_POST['interface']) {
100
		$interface = htmlspecialchars(trim($_POST['interface']));
101
	}
102
	if ($_POST['parentqueue']) {
103
		$parentqueue = htmlspecialchars(trim($_POST['parentqueue']));
104
	}
105
}
106

    
107
if ($interface) {
108
	$altq = $altq_list_queues[$interface];
109

    
110
	if ($altq) {
111
		$queue =& $altq->find_queue($interface, $qname);
112
	} else {
113
		$addnewaltq = true;
114
	}
115
}
116

    
117
$dontshow = false;
118
$newqueue = false;
119
$dfltmsg = false;
120

    
121
if ($_GET) {
122
	switch ($action) {
123
		case "delete":
124
			if ($queue) {
125
				$queue->delete_queue();
126
				if (write_config()) {
127
					mark_subsystem_dirty('shaper');
128
				}
129
			}
130

    
131
			header("Location: firewall_shaper.php");
132
			exit;
133
			break;
134
		case "resetall":
135
			foreach ($altq_list_queues as $altq) {
136
				$altq->delete_all();
137
			}
138
			unset($altq_list_queues);
139
			$altq_list_queues = array();
140
			$tree = "<ul class=\"tree\" >";
141
			$tree .= get_interface_list_to_show();
142
			$tree .= "</ul>";
143
			unset($config['shaper']['queue']);
144
			unset($queue);
145
			unset($altq);
146
			$can_add = false;
147
			$can_enable = false;
148
			$dontshow = true;
149
			foreach ($config['filter']['rule'] as $key => $rule) {
150
				if (isset($rule['wizard']) && $rule['wizard'] == "yes") {
151
					unset($config['filter']['rule'][$key]);
152
				}
153
			}
154

    
155
			if (write_config()) {
156
				$retval = 0;
157
				$retval |= filter_configure();
158

    
159
				if (stristr($retval, "error") <> true) {
160
					$savemsg = get_std_save_message($retval);
161
					$class = 'success';
162
				} else {
163
					$savemsg = $retval;
164
					$class = 'warning';
165
				}
166
			} else {
167
				$savemsg = gettext("Unable to write config.xml (Access Denied?).");
168
				$class = 'warning';
169
			}
170

    
171
			$dfltmsg = true;
172

    
173

    
174
		break;
175

    
176
	case "add":
177
			/* XXX: Find better way because we shouldn't know about this */
178
		if ($altq) {
179

    
180
			switch ($altq->GetScheduler()) {
181
				case "PRIQ":
182
					$q = new priq_queue();
183
				break;
184
				case "FAIRQ":
185
					$q = new fairq_queue();
186
				break;
187
				case "HFSC":
188
					$q = new hfsc_queue();
189
				break;
190
				case "CBQ":
191
						$q = new cbq_queue();
192
				break;
193
				default:
194
					/* XXX: Happens when sched==NONE?! */
195
					$q = new altq_root_queue();
196
				break;
197
			}
198
		} else if ($addnewaltq) {
199
			$q = new altq_root_queue();
200
		} else {
201
			$input_errors[] = gettext("Could not create new queue/discipline! Any recent changes may need to be applied first.");
202
		}
203

    
204
		if ($q) {
205
			$q->SetInterface($interface);
206
			$sform = $q->build_form();
207
			$sform->addGlobal(new Form_Input(
208
				'parentqueue',
209
				null,
210
				'hidden',
211
				$qname
212
			));
213

    
214
			$newjavascript = $q->build_javascript();
215
			unset($q);
216
			$newqueue = true;
217
		}
218
		break;
219
		case "show":
220
			if ($queue) {
221
				$sform = $queue->build_form();
222
			} else {
223
				$input_errors[] = gettext("Queue not found!");
224
			}
225
		break;
226
		case "enable":
227
			if ($queue) {
228
				$queue->SetEnabled("on");
229
				$sform = $queue->build_form();
230
				if (write_config()) {
231
					mark_subsystem_dirty('shaper');
232
				}
233
			} else {
234
				$input_errors[] = gettext("Queue not found!");
235
			}
236
			break;
237
		case "disable":
238
			if ($queue) {
239
				$queue->SetEnabled("");
240
				$sform = $queue->build_form();
241
				if (write_config()) {
242
					mark_subsystem_dirty('shaper');
243
				}
244
			} else {
245
				$input_errors[] = gettext("Queue not found!");
246
			}
247
			break;
248
		default:
249
			$dfltmsg = true;
250
			$dontshow = true;
251
			break;
252
	}
253
}
254

    
255
if ($_POST) {
256
	unset($input_errors);
257

    
258
	if ($addnewaltq) {
259
		$altq =& new altq_root_queue();
260
		$altq->SetInterface($interface);
261
		$altq->ReadConfig($_POST);
262
		$altq->validate_input($_POST, $input_errors);
263
		if (!$input_errors) {
264
			unset($tmppath);
265
			$tmppath[] = $altq->GetInterface();
266
			$altq->SetLink($tmppath);
267
			$altq->wconfig();
268
			if (write_config()) {
269
				mark_subsystem_dirty('shaper');
270
			}
271
			$can_enable = true;
272
			$can_add = true;
273
		}
274

    
275
		read_altq_config();
276
		$sform = $altq->build_form();
277
	} else if ($parentqueue) { /* Add a new queue */
278
		$qtmp =& $altq->find_queue($interface, $parentqueue);
279
		if ($qtmp) {
280
			$tmppath =& $qtmp->GetLink();
281
			array_push($tmppath, $qname);
282
			$tmp =& $qtmp->add_queue($interface, $_POST, $tmppath, $input_errors);
283
			if (!$input_errors) {
284
				array_pop($tmppath);
285
				$tmp->wconfig();
286
				$can_enable = true;
287
				if ($tmp->CanHaveChildren() && $can_enable) {
288
					if ($tmp->GetDefault() <> "") {
289
						$can_add = false;
290
					} else {
291
						$can_add = true;
292
					}
293
				} else {
294
					$can_add = false;
295
				}
296
				if (write_config()) {
297
					mark_subsystem_dirty('shaper');
298
				}
299
				$can_enable = true;
300
				if ($altq->GetScheduler() != "PRIQ") { /* XXX */
301
					if ($tmp->GetDefault() <> "") {
302
						$can_add = false;
303
					} else {
304
						$can_add = true;
305
					}
306
				}
307
			}
308
			read_altq_config();
309
			$sform = $tmp->build_form();
310
		} else {
311
			$input_errors[] = gettext("Could not add new queue.");
312
		}
313
	} else if ($_POST['apply']) {
314
		write_config();
315

    
316
		$retval = 0;
317
		$retval = filter_configure();
318

    
319
		if (stristr($retval, "error") <> true) {
320
			$savemsg = get_std_save_message($retval);
321
			$class = 'success';
322
		} else {
323
			$savemsg = $retval;
324
			$class = 'warning';
325
		}
326

    
327
		/* reset rrd queues */
328
		system("rm -f /var/db/rrd/*queuedrops.rrd");
329
		system("rm -f /var/db/rrd/*queues.rrd");
330
		enable_rrd_graphing();
331

    
332
		clear_subsystem_dirty('shaper');
333

    
334
		if ($queue) {
335
			$sform = $queue->build_form();
336
			$dontshow = false;
337
		} else {
338
			$sform = $default_shaper_message;
339
			$dontshow = true;
340
		}
341
	} else if ($queue) {
342
		$queue->validate_input($_POST, $input_errors);
343
		if (!$input_errors) {
344
			$queue->update_altq_queue_data($_POST);
345
			$queue->wconfig();
346
			if (write_config()) {
347
				mark_subsystem_dirty('shaper');
348
			}
349
			$dontshow = false;
350
		}
351
		read_altq_config();
352
		$sform = $queue->build_form();
353
	} else	{
354
		$dfltmsg = true;
355
		$dontshow = true;
356
	}
357
	mwexec("killall qstats");
358
}
359

    
360
if (!$_POST && !$_GET) {
361
	$dfltmsg = true;
362
	$dontshow = true;
363
}
364

    
365
if ($queue) {
366
	if ($queue->GetEnabled()) {
367
		$can_enable = true;
368
	} else {
369
		$can_enable = false;
370
	}
371
	if ($queue->CanHaveChildren() && $can_enable) {
372
		if ($altq->GetQname() <> $queue->GetQname() && $queue->GetDefault() <> "") {
373
			$can_add = false;
374
		} else {
375
			$can_add = true;
376
		}
377
	} else {
378
		$can_add = false;
379
	}
380
}
381

    
382
include("head.inc");
383

    
384
$tree = '<ul class="tree" >';
385
if (is_array($altq_list_queues)) {
386
	foreach ($altq_list_queues as $tmpaltq) {
387
		$tree .= $tmpaltq->build_tree();
388
	}
389
	$tree .= get_interface_list_to_show();
390
}
391

    
392
$tree .= "</ul>";
393

    
394
if ($queue) {
395
	print($queue->build_javascript());
396
}
397

    
398
print($newjavascript);
399

    
400
if ($input_errors) {
401
	print_input_errors($input_errors);
402
}
403

    
404
if ($savemsg) {
405
	print_info_box($savemsg, $class);
406
}
407

    
408
if (is_subsystem_dirty('shaper')) {
409
	print_apply_box(gettext("The traffic shaper configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect."));
410
}
411

    
412
$tab_array = array();
413
$tab_array[] = array(gettext("By Interface"), true, "firewall_shaper.php");
414
$tab_array[] = array(gettext("By Queue"), false, "firewall_shaper_queues.php");
415
$tab_array[] = array(gettext("Limiters"), false, "firewall_shaper_vinterface.php");
416
$tab_array[] = array(gettext("Wizards"), false, "firewall_shaper_wizards.php");
417
display_top_tabs($tab_array);
418

    
419
?>
420
<script type="text/javascript" src="./vendor/tree/tree.js"></script>
421

    
422
<div class="table-responsive">
423
	<table class="table">
424
		<tbody>
425
			<tr class="tabcont">
426
				<td class="col-md-1">
427
<?php
428
// Display the shaper tree
429
print($tree);
430

    
431
if (count($altq_list_queues) > 0) {
432
?>
433
					<a href="firewall_shaper.php?action=resetall" class="btn btn-sm btn-danger">
434
						<i class="fa fa-trash icon-embed-btn"></i>
435
						<?=gettext('Remove Shaper')?>
436
					</a>
437
<?php
438
}
439
?>
440
				</td>
441
				<td>
442
<?php
443

    
444
if (!$dfltmsg && $sform)  {
445
	// Add global buttons
446
	if (!$dontshow || $newqueue) {
447
		if ($can_add || $addnewaltq) {
448
			if ($queue) {
449
				$url = 'firewall_shaper.php?interface='. $interface . '&queue=' . $queue->GetQname() . '&action=add';
450
			} else {
451
				$url = 'firewall_shaper.php?interface='. $interface . '&action=add';
452
			}
453

    
454
			$sform->addGlobal(new Form_Button(
455
				'add',
456
				'Add new Queue',
457
				$url,
458
				'fa-plus'
459
			))->addClass('btn-success');
460

    
461
		}
462

    
463
		if ($queue) {
464
			$url = 'firewall_shaper.php?interface='. $interface . '&queue=' . $queue->GetQname() . '&action=delete';
465
		} else {
466
			$url = 'firewall_shaper.php?interface='. $interface . '&action=delete';
467
		}
468

    
469
		$sform->addGlobal(new Form_Button(
470
			'delete',
471
			$queue ? 'Delete this queue':'Disable shaper on interface',
472
			$url,
473
			'fa-trash'
474
		))->addClass('btn-danger');
475

    
476
	}
477

    
478
	print($sform);
479
}
480
?>
481
				</td>
482
			</tr>
483
		</tbody>
484
	</table>
485
</div>
486

    
487
<?php
488
if ($dfltmsg) {
489
?>
490
<div>
491
	<div class="infoblock">
492
		<?php print_info_box($default_shaper_msg, 'info', false); ?>
493
	</div>
494
</div>
495
<?php
496
}
497
include("foot.inc");
(52-52/227)