Project

General

Profile

Download (8.78 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	interfaces_qinq_edit.php
4

    
5
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
6
	Copyright (C) 2009 Ermal Luçi
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 the
17
	   documentation and/or other materials provided with the distribution.
18

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

    
35
##|+PRIV
36
##|*IDENT=page-interfaces-qinq-edit
37
##|*NAME=Interfaces: QinQ: Edit page
38
##|*DESCR=Allow access to 'Interfaces: QinQ: Edit' page
39
##|*MATCH=interfaces_qinq_edit.php*
40
##|-PRIV
41

    
42
$pgtitle = array(gettext("Interfaces"),gettext("QinQ"), gettext("Edit"));
43
$shortcut_section = "interfaces";
44

    
45
require("guiconfig.inc");
46

    
47
if (!is_array($config['qinqs']['qinqentry']))
48
	$config['qinqs']['qinqentry'] = array();
49

    
50
$a_qinqs = &$config['qinqs']['qinqentry'];
51

    
52
$portlist = get_interface_list();
53

    
54
/* add LAGG interfaces */
55
if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
56
	foreach ($config['laggs']['lagg'] as $lagg)
57
			$portlist[$lagg['laggif']] = $lagg;
58
}
59

    
60
if (count($portlist) < 1) {
61
	header("Location: interfaces_qinq.php");
62
	exit;
63
}
64

    
65
if (is_numericint($_GET['id']))
66
	$id = $_GET['id'];
67

    
68
if (isset($_POST['id']) && is_numericint($_POST['id']))
69
	$id = $_POST['id'];
70

    
71
if (isset($id) && $a_qinqs[$id]) {
72
	$pconfig['if'] = $a_qinqs[$id]['if'];
73
	$pconfig['tag'] = $a_qinqs[$id]['tag'];
74
	$pconfig['members'] = $a_qinqs[$id]['members'];
75
	$pconfig['descr'] = html_entity_decode($a_qinqs[$id]['descr']);
76
	$pconfig['autogroup'] = isset($a_qinqs[$id]['autogroup']);
77
	$pconfig['autoadjustmtu'] = isset($a_qinqs[$id]['autoadjustmtu']);
78
}
79

    
80
if ($_POST) {
81
	unset($input_errors);
82
	$pconfig = $_POST;
83

    
84
	if (empty($_POST['tag']))
85
		$input_errors[] = gettext("First level tag cannot be empty.");
86
	if (isset($id) && $a_qinqs[$id]['tag'] != $_POST['tag'])
87
		$input_errors[] = gettext("You are editing an existing entry and modifying the first level tag is not allowed.");
88
	if (isset($id) && $a_qinqs[$id]['if'] != $_POST['if'])
89
		$input_errors[] = gettext("You are editing an existing entry and modifying the interface is not allowed.");
90
	if (!isset($id)) {
91
		foreach ($a_qinqs as $qinqentry) {
92
			if ($qinqentry['tag'] == $_POST['tag'] && $qinqentry['if'] == $_POST['if'])
93
				$input_errors[] = gettext("QinQ level already exists for this interface, edit it!");
94
			}
95

    
96
		if (is_array($config['vlans']['vlan'])) {
97
			foreach ($config['vlans']['vlan'] as $vlan)
98
				if ($vlan['tag'] == $_POST['tag'] && $vlan['if'] == $_POST['if'])
99
					$input_errors[] = gettext("A normal VLAN exists with this tag please remove it to use this tag for QinQ first level.");
100
		}
101
	}
102

    
103
	$qinqentry = array();
104
	$qinqentry['if'] = $_POST['if'];
105
	$qinqentry['tag'] = $_POST['tag'];
106

    
107
	if ($_POST['autogroup'] == "yes")
108
		$qinqentry['autogroup'] = true;
109

    
110
	$members = "";
111
	$isfirst = 0;
112

    
113
	// Read the POSTed member array into a space separated list translating any ranges
114
	// into their included values
115
	foreach ($_POST['members'] as $memb) {
116
		// Might be a range
117
		$member = explode("-", $memb);
118

    
119
		if (count($member) > 1) {
120
			if (preg_match("/([^0-9])+/", $member[0], $match)  || preg_match("/([^0-9])+/", $member[1], $match))
121
				$input_errors[] = gettext("Tags can contain only numbers or a range in format #-#.");
122

    
123
			for ($i = $member[0]; $i <= $member[1]; $i++) {
124
				$members .= ($isfirst == 0 ? '':' ') . $i;
125
				$isfirst++;
126
			}
127
		}
128
		else { // Just a single number
129
			if (preg_match("/([^0-9])+/", $memb, $match))
130
				$input_errors[] = gettext("Tags can contain only numbers or a range in format #-#.");
131
			else {
132
				$members .= ($isfirst == 0 ? '':' ') . $memb;
133
				$isfirst++;
134
			}
135
		}
136
	}
137

    
138
	if (!$input_errors) {
139
		$qinqentry['members'] = $members;
140
		$qinqentry['descr'] = $_POST['descr'];
141
		$qinqentry['vlanif'] = "{$_POST['if']}_{$_POST['tag']}";
142
		$nmembers = explode(" ", $members);
143

    
144
		if (isset($id) && $a_qinqs[$id]) {
145
			$omembers = explode(" ", $a_qinqs[$id]['members']);
146
			$delmembers = array_diff($omembers, $nmembers);
147
			$addmembers = array_diff($nmembers, $omembers);
148

    
149
			if ((count($delmembers) > 0) || (count($addmembers) > 0)) {
150
				$fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
151
				foreach ($delmembers as $tag) {
152
					fwrite($fd, "shutdown {$qinqentry['vlanif']}h{$tag}:\n");
153
					fwrite($fd, "msg {$qinqentry['vlanif']}qinq: delfilter \\\"{$qinqentry['vlanif']}{$tag}\\\"\n");
154
				}
155

    
156
				foreach ($addmembers as $member) {
157
					$qinq = array();
158
					$qinq['if'] = $qinqentry['vlanif'];
159
					$qinq['tag'] = $member;
160
					$macaddr = get_interface_mac($qinqentry['vlanif']);
161
					interface_qinq2_configure($qinq, $fd, $macaddr);
162
				}
163

    
164
				fclose($fd);
165
				mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
166
			}
167
			$a_qinqs[$id] = $qinqentry;
168
		} else {
169
			interface_qinq_configure($qinqentry);
170
			$a_qinqs[] = $qinqentry;
171
		}
172
		if ($_POST['autogroup'] == "yes") {
173
			if (!is_array($config['ifgroups']['ifgroupentry']))
174
				$config['ifgroups']['ifgroupentry'] = array();
175
			foreach ($config['ifgroups']['ifgroupentry'] as $gid => $group) {
176
				if ($group['ifname'] == "QinQ") {
177
					$found = true;
178
					break;
179
				}
180
			}
181
			$additions = "";
182
			foreach($nmembers as $qtag)
183
				$additions .= "{$qinqentry['vlanif']}_{$qtag} ";
184
			$additions .= "{$qinqentry['vlanif']}";
185
			if ($found == true)
186
				$config['ifgroups']['ifgroupentry'][$gid]['members'] .= " {$additions}";
187
			else {
188
				$gentry = array();
189
				$gentry['ifname'] = "QinQ";
190
				$gentry['members'] = "{$additions}";
191
				$gentry['descr'] = gettext("QinQ VLANs group");
192
				$config['ifgroups']['ifgroupentry'][] = $gentry;
193
			}
194
		}
195

    
196
		write_config();
197

    
198
		header("Location: interfaces_qinq.php");
199
		exit;
200
	} else {
201
		$pconfig['descr'] = $_POST['descr'];
202
		$pconfig['tag'] = $_POST['tag'];
203
		$pconfig['members'] = $members;
204
	}
205
}
206

    
207
function build_parent_list() {
208
	global $portlist;
209

    
210
	$list = array();
211

    
212
	foreach ($portlist as $ifn => $ifinfo) {
213
		if (is_jumbo_capable($ifn))
214
			$list[$ifn] = $ifn . ' (' . $ifinfo['mac'] . ')';
215
	}
216

    
217
	return($list);
218
}
219

    
220
include("head.inc");
221

    
222
if ($input_errors) 
223
	print_input_errors($input_errors);
224

    
225
require('classes/Form.class.php');
226

    
227
$form = new Form(new Form_Button(
228
	'Submit',
229
	gettext("Save")
230
));
231

    
232
$section = new Form_Section('Interface QinQ Edit');
233

    
234
$section->addInput(new Form_Select(
235
	'if',
236
	'Parent interface',
237
	$pconfig['if'],
238
	build_parent_list()
239
))->setHelp('Only QinQ capable interfaces will be shown.');
240

    
241
$section->addInput(new Form_Input(
242
	'tag',
243
	'First level tag',
244
	'number',
245
	$pconfig['tag'],
246
	['max' => '4094', 'min' => '1']
247
))->setHelp('This is the first level VLAN tag. On top of this are stacked the member VLANs defined below.');
248

    
249
$section->addInput(new Form_Checkbox(
250
	'autogroup',
251
	'Option(s)',
252
	'Adds interface to QinQ interface groups',
253
	$pconfig['autogroup']
254
))->setHelp('Allows rules to be written more easily');
255

    
256
$section->addInput(new Form_Input(
257
	'descr',
258
	'Description',
259
	'text',
260
	$pconfig['descr']
261
))->setHelp('You may enter a description here for your reference (not parsed).');
262

    
263
$section->addInput(new Form_StaticText(
264
	'Member(s)',
265
	'You can specify ranges in the inputs below. Enter a range (2-3) or individual numbers.' . '<br />' .
266
	'Click "Duplicate" as many times as needed to add new inputs'
267
));
268

    
269
if (isset($id) && $a_qinqs[$id]) {
270
	$section->addInput(new Form_Input(
271
		'id',
272
		null,
273
		'hidden',
274
		$id
275
	));
276
}
277

    
278
$counter = 0;
279
$members = $pconfig['members'];
280

    
281
// List each of the member tags from the space-separated list
282
if ($members != "")
283
	$item = explode(" ", $members);
284
else
285
	$item = array('');
286

    
287
foreach($item as $ww) {
288
	$member = $item[$counter];
289

    
290
	$group = new Form_Group($counter == 0 ? 'Tag(s)':'');
291

    
292
	$group->add(new Form_Input(
293
		'members',
294
		null,
295
		'text',
296
		$ww
297
	))->setWidth(6); // Width must be <= 8 to make room for the duplication buttons
298

    
299
$counter++;
300

    
301
$group->enableDuplication(null, true); // Buttons are in-line with the input
302
$section->add($group);
303
}
304

    
305
$form->add($section);
306

    
307
print($form);
308

    
309
include("foot.inc");
(97-97/237)