Project

General

Profile

Download (18 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	interfaces_assign.php
4
	part of m0n0wall (http://m0n0.ch/wall)
5
	Written by Jim McBeath based on existing m0n0wall files
6

    
7
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
8
	Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
9
	All rights reserved.
10

    
11
	Redistribution and use in source and binary forms, with or without
12
	modification, are permitted provided that the following conditions are met:
13

    
14
	1. Redistributions of source code must retain the above copyright notice,
15
	   this list of conditions and the following disclaimer.
16

    
17
	2. Redistributions in binary form must reproduce the above copyright
18
	   notice, this list of conditions and the following disclaimer in the
19
	   documentation and/or other materials provided with the distribution.
20

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

    
37
##|+PRIV
38
##|*IDENT=page-interfaces-assignnetworkports
39
##|*NAME=Interfaces: Assign network ports page
40
##|*DESCR=Allow access to the 'Interfaces: Assign network ports' page.
41
##|*MATCH=interfaces_assign.php*
42
##|-PRIV
43

    
44
$pgtitle = array(gettext("Interfaces"), gettext("Assign network ports"));
45
$shortcut_section = "interfaces";
46

    
47
require("guiconfig.inc");
48
require("functions.inc");
49
require_once("filter.inc");
50
require("shaper.inc");
51
require("ipsec.inc");
52
require("vpn.inc");
53
require("captiveportal.inc");
54
require_once("rrd.inc");
55

    
56
function interface_assign_description($portinfo, $portname) {
57
	global $ovpn_descrs;
58
	if ($portinfo['isvlan']) {
59
		$descr = sprintf(gettext('VLAN %1$s on %2$s'), $portinfo['tag'], $portinfo['if']);
60
		if ($portinfo['descr']) {
61
			$descr .= " (" . $portinfo['descr'] . ")";
62
		}
63
	} elseif ($portinfo['iswlclone']) {
64
		$descr = $portinfo['cloneif'];
65
		if ($portinfo['descr']) {
66
			$descr .= " (" . $portinfo['descr'] . ")";
67
		}
68
	} elseif ($portinfo['isppp']) {
69
		$descr = $portinfo['descr'];
70
	} elseif ($portinfo['isbridge']) {
71
		$descr = strtoupper($portinfo['bridgeif']);
72
		if ($portinfo['descr']) {
73
			$descr .= " (" . $portinfo['descr'] . ")";
74
		}
75
	} elseif ($portinfo['isgre']) {
76
		$descr = "GRE {$portinfo['remote-addr']}";
77
		if ($portinfo['descr']) {
78
			$descr .= " (" . $portinfo['descr'] . ")";
79
		}
80
	} elseif ($portinfo['isgif']) {
81
		$descr = "GIF {$portinfo['remote-addr']}";
82
		if ($portinfo['descr']) {
83
			$descr .= " (" . $portinfo['descr'] . ")";
84
		}
85
	} elseif ($portinfo['islagg']) {
86
		$descr = strtoupper($portinfo['laggif']);
87
		if ($portinfo['descr']) {
88
			$descr .= " (" . $portinfo['descr'] . ")";
89
		}
90
	} elseif ($portinfo['isqinq']) {
91
		$descr = $portinfo['descr'];
92
	} elseif (substr($portname, 0, 4) == 'ovpn') {
93
		$descr = $portname . " (" . $ovpn_descrs[substr($portname, 5)] . ")";
94
	} else {
95
		$descr = $portname . " (" . $portinfo['mac'] . ")";
96
	}
97

    
98
	return htmlspecialchars($descr);
99
}
100

    
101
/*
102
	In this file, "port" refers to the physical port name,
103
	while "interface" refers to LAN, WAN, or OPTn.
104
*/
105

    
106
/* get list without VLAN interfaces */
107
$portlist = get_interface_list();
108

    
109
/* add wireless clone interfaces */
110
if (is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
111
	foreach ($config['wireless']['clone'] as $clone) {
112
		$portlist[$clone['cloneif']] = $clone;
113
		$portlist[$clone['cloneif']]['iswlclone'] = true;
114
	}
115
}
116

    
117
/* add VLAN interfaces */
118
if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
119
	foreach ($config['vlans']['vlan'] as $vlan) {
120
		$portlist[$vlan['vlanif']] = $vlan;
121
		$portlist[$vlan['vlanif']]['isvlan'] = true;
122
	}
123
}
124

    
125
/* add Bridge interfaces */
126
if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
127
	foreach ($config['bridges']['bridged'] as $bridge) {
128
		$portlist[$bridge['bridgeif']] = $bridge;
129
		$portlist[$bridge['bridgeif']]['isbridge'] = true;
130
	}
131
}
132

    
133
/* add GIF interfaces */
134
if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
135
	foreach ($config['gifs']['gif'] as $gif) {
136
		$portlist[$gif['gifif']] = $gif;
137
		$portlist[$gif['gifif']]['isgif'] = true;
138
	}
139
}
140

    
141
/* add GRE interfaces */
142
if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
143
	foreach ($config['gres']['gre'] as $gre) {
144
		$portlist[$gre['greif']] = $gre;
145
		$portlist[$gre['greif']]['isgre'] = true;
146
	}
147
}
148

    
149
/* add LAGG interfaces */
150
if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
151
	foreach ($config['laggs']['lagg'] as $lagg) {
152
		$portlist[$lagg['laggif']] = $lagg;
153
		$portlist[$lagg['laggif']]['islagg'] = true;
154
		/* LAGG members cannot be assigned */
155
		$lagifs = explode(',', $lagg['members']);
156
		foreach ($lagifs as $lagif) {
157
			if (isset($portlist[$lagif])) {
158
				unset($portlist[$lagif]);
159
			}
160
		}
161
	}
162
}
163

    
164
/* add QinQ interfaces */
165
if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
166
	foreach ($config['qinqs']['qinqentry'] as $qinq) {
167
		$portlist["vlan{$qinq['tag']}"]['descr'] = "VLAN {$qinq['tag']}";
168
		$portlist["vlan{$qinq['tag']}"]['isqinq'] = true;
169
		/* QinQ members */
170
		$qinqifs = explode(' ', $qinq['members']);
171
		foreach ($qinqifs as $qinqif) {
172
			$portlist["vlan{$qinq['tag']}_{$qinqif}"]['descr'] = "QinQ {$qinqif}";
173
			$portlist["vlan{$qinq['tag']}_{$qinqif}"]['isqinq'] = true;
174
		}
175
	}
176
}
177

    
178
/* add PPP interfaces */
179
if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
180
	foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
181
		$portname = $ppp['if'];
182
		$portlist[$portname] = $ppp;
183
		$portlist[$portname]['isppp'] = true;
184
		$ports_base = basename($ppp['ports']);
185
		if (isset($ppp['descr'])) {
186
			$portlist[$portname]['descr'] = strtoupper($ppp['if']). "({$ports_base}) - {$ppp['descr']}";
187
		} else if (isset($ppp['username'])) {
188
			$portlist[$portname]['descr'] = strtoupper($ppp['if']). "({$ports_base}) - {$ppp['username']}";
189
		} else {
190
			$portlist[$portname]['descr'] = strtoupper($ppp['if']). "({$ports_base})";
191
		}
192
	}
193
}
194

    
195
$ovpn_descrs = array();
196
if (is_array($config['openvpn'])) {
197
	if (is_array($config['openvpn']['openvpn-server'])) {
198
		foreach ($config['openvpn']['openvpn-server'] as $s) {
199
			$portname = "ovpns{$s['vpnid']}";
200
			$portlist[$portname] = $s;
201
			$ovpn_descrs[$s['vpnid']] = $s['description'];
202
		}
203
	}
204
	if (is_array($config['openvpn']['openvpn-client'])) {
205
		foreach ($config['openvpn']['openvpn-client'] as $c) {
206
			$portname = "ovpnc{$c['vpnid']}";
207
			$portlist[$portname] = $c;
208
			$ovpn_descrs[$c['vpnid']] = $c['description'];
209
		}
210
	}
211
}
212

    
213
if (isset($_POST['add']) && isset($_POST['if_add'])) {
214
	/* Be sure this port is not being used */
215
	$portused = false;
216
	foreach ($config['interfaces'] as $ifname => $ifdata) {
217
		if ($ifdata['if'] == $_POST['if_add']) {
218
			$portused = true;
219
			break;
220
		}
221
	}
222

    
223
	if ($portused === false) {
224
		/* find next free optional interface number */
225
		if (!$config['interfaces']['lan']) {
226
			$newifname = gettext("lan");
227
			$descr = gettext("LAN");
228
		} else {
229
			for ($i = 1; $i <= count($config['interfaces']); $i++) {
230
				if (!$config['interfaces']["opt{$i}"]) {
231
					break;
232
				}
233
			}
234
			$newifname = 'opt' . $i;
235
			$descr = "OPT" . $i;
236
		}
237

    
238
		$config['interfaces'][$newifname] = array();
239
		$config['interfaces'][$newifname]['descr'] = $descr;
240
		$config['interfaces'][$newifname]['if'] = $_POST['if_add'];
241
		if (preg_match($g['wireless_regex'], $_POST['if_add'])) {
242
			$config['interfaces'][$newifname]['wireless'] = array();
243
			interface_sync_wireless_clones($config['interfaces'][$newifname], false);
244
		}
245

    
246
		uksort($config['interfaces'], "compare_interface_friendly_names");
247

    
248
		/* XXX: Do not remove this. */
249
		unlink_if_exists("{$g['tmp_path']}/config.cache");
250

    
251
		write_config();
252

    
253
		$savemsg = gettext("Interface has been added.");
254
	}
255

    
256
} else if (isset($_POST['apply'])) {
257
	if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
258
		system_reboot();
259
		$rebootingnow = true;
260
	} else {
261
		write_config();
262

    
263
		$retval = filter_configure();
264
		$savemsg = get_std_save_message($retval);
265

    
266
		if (stristr($retval, "error") <> true) {
267
			$savemsg = get_std_save_message($retval);
268
		} else {
269
			$savemsg = $retval;
270
		}
271
	}
272

    
273
} else if (isset($_POST['Submit'])) {
274

    
275
	unset($input_errors);
276

    
277
	/* input validation */
278

    
279
	/* Build a list of the port names so we can see how the interfaces map */
280
	$portifmap = array();
281
	foreach ($portlist as $portname => $portinfo) {
282
		$portifmap[$portname] = array();
283
	}
284

    
285
	/* Go through the list of ports selected by the user,
286
	build a list of port-to-interface mappings in portifmap */
287
	foreach ($_POST as $ifname => $ifport) {
288
		if (($ifname == 'lan') || ($ifname == 'wan') || (substr($ifname, 0, 3) == 'opt')) {
289
			$portifmap[$ifport][] = strtoupper($ifname);
290
		}
291
	}
292

    
293
	/* Deliver error message for any port with more than one assignment */
294
	foreach ($portifmap as $portname => $ifnames) {
295
		if (count($ifnames) > 1) {
296
			$errstr = sprintf(gettext('Port %1$s '.
297
				' was assigned to %2$s' .
298
				' interfaces:'), $portname, count($ifnames));
299

    
300
			foreach ($portifmap[$portname] as $ifn) {
301
				$errstr .= " " . convert_friendly_interface_to_friendly_descr(strtolower($ifn)) . " (" . $ifn . ")";
302
			}
303

    
304
			$input_errors[] = $errstr;
305
		} else if (count($ifnames) == 1 && preg_match('/^bridge[0-9]/', $portname) && is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
306
			foreach ($config['bridges']['bridged'] as $bridge) {
307
				if ($bridge['bridgeif'] != $portname) {
308
					continue;
309
				}
310

    
311
				$members = explode(",", strtoupper($bridge['members']));
312
				foreach ($members as $member) {
313
					if ($member == $ifnames[0]) {
314
						$input_errors[] = sprintf(gettext("You cannot set port %s to interface %s because this interface is a member of %s."), $portname, $member, $portname);
315
						break;
316
					}
317
				}
318
			}
319
		}
320
	}
321

    
322
	if (is_array($config['vlans']['vlan'])) {
323
		foreach ($config['vlans']['vlan'] as $vlan) {
324
			if (does_interface_exist($vlan['if']) == false) {
325
				$input_errors[] = "Vlan parent interface {$vlan['if']} does not exist anymore so vlan id {$vlan['tag']} cannot be created please fix the issue before continuing.";
326
			}
327
		}
328
	}
329

    
330
	if (!$input_errors) {
331
		/* No errors detected, so update the config */
332
		foreach ($_POST as $ifname => $ifport) {
333

    
334
			if (($ifname == 'lan') || ($ifname == 'wan') || (substr($ifname, 0, 3) == 'opt')) {
335

    
336
				if (!is_array($ifport)) {
337
					$reloadif = false;
338
					if (!empty($config['interfaces'][$ifname]['if']) && $config['interfaces'][$ifname]['if'] <> $ifport) {
339
						interface_bring_down($ifname);
340
						/* Mark this to be reconfigured in any case. */
341
						$reloadif = true;
342
					}
343
					$config['interfaces'][$ifname]['if'] = $ifport;
344
					if (isset($portlist[$ifport]['isppp'])) {
345
						$config['interfaces'][$ifname]['ipaddr'] = $portlist[$ifport]['type'];
346
					}
347

    
348
					if (substr($ifport, 0, 3) == 'gre' || substr($ifport, 0, 3) == 'gif') {
349
						unset($config['interfaces'][$ifname]['ipaddr']);
350
						unset($config['interfaces'][$ifname]['subnet']);
351
						unset($config['interfaces'][$ifname]['ipaddrv6']);
352
						unset($config['interfaces'][$ifname]['subnetv6']);
353
					}
354

    
355
					/* check for wireless interfaces, set or clear ['wireless'] */
356
					if (preg_match($g['wireless_regex'], $ifport)) {
357
						if (!is_array($config['interfaces'][$ifname]['wireless'])) {
358
							$config['interfaces'][$ifname]['wireless'] = array();
359
						}
360
					} else {
361
						unset($config['interfaces'][$ifname]['wireless']);
362
					}
363

    
364
					/* make sure there is a descr for all interfaces */
365
					if (!isset($config['interfaces'][$ifname]['descr'])) {
366
						$config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
367
					}
368

    
369
					if ($reloadif == true) {
370
						if (preg_match($g['wireless_regex'], $ifport)) {
371
							interface_sync_wireless_clones($config['interfaces'][$ifname], false);
372
						}
373
						/* Reload all for the interface. */
374
						interface_configure($ifname, true);
375
					}
376
				}
377
			}
378
		}
379

    
380
		write_config();
381

    
382
		enable_rrd_graphing();
383
	}
384
} else {
385
	unset($delbtn);
386
	if (!empty($_POST['del']))
387
		$delbtn = key($_POST['del']);
388

    
389
	if (isset($delbtn)) {
390
		$id = $delbtn;
391

    
392
		if (link_interface_to_group($id)) {
393
			$input_errors[] = gettext("The interface is part of a group. Please remove it from the group to continue");
394
		} else if (link_interface_to_bridge($id)) {
395
			$input_errors[] = gettext("The interface is part of a bridge. Please remove it from the bridge to continue");
396
		} else if (link_interface_to_gre($id)) {
397
			$input_errors[] = gettext("The interface is part of a gre tunnel. Please delete the tunnel to continue");
398
		} else if (link_interface_to_gif($id)) {
399
			$input_errors[] = gettext("The interface is part of a gif tunnel. Please delete the tunnel to continue");
400
		} else {
401
			unset($config['interfaces'][$id]['enable']);
402
			$realid = get_real_interface($id);
403
			interface_bring_down($id);   /* down the interface */
404

    
405
			unset($config['interfaces'][$id]);	/* delete the specified OPTn or LAN*/
406

    
407
			if (is_array($config['dhcpd']) && is_array($config['dhcpd'][$id])) {
408
				unset($config['dhcpd'][$id]);
409
				services_dhcpd_configure();
410
			}
411

    
412
			if (count($config['filter']['rule']) > 0) {
413
				foreach ($config['filter']['rule'] as $x => $rule) {
414
					if ($rule['interface'] == $id) {
415
						unset($config['filter']['rule'][$x]);
416
					}
417
				}
418
			}
419
			if (is_array($config['nat']['rule']) && count($config['nat']['rule']) > 0) {
420
				foreach ($config['nat']['rule'] as $x => $rule) {
421
					if ($rule['interface'] == $id) {
422
						unset($config['nat']['rule'][$x]['interface']);
423
					}
424
				}
425
			}
426

    
427
			write_config();
428

    
429
			/* If we are in firewall/routing mode (not single interface)
430
			 * then ensure that we are not running DHCP on the wan which
431
			 * will make a lot of ISP's unhappy.
432
			 */
433
			if ($config['interfaces']['lan'] && $config['dhcpd']['wan']) {
434
				unset($config['dhcpd']['wan']);
435
			}
436

    
437
			link_interface_to_vlans($realid, "update");
438

    
439
			$savemsg = gettext("Interface has been deleted.");
440
		}
441
	}
442
}
443

    
444
/* Create a list of unused ports */
445
$unused_portlist = array();
446
foreach ($portlist as $portname => $portinfo) {
447
	$portused = false;
448
	foreach ($config['interfaces'] as $ifname => $ifdata) {
449
		if ($ifdata['if'] == $portname) {
450
			$portused = true;
451
			break;
452
		}
453
	}
454
	if ($portused === false) {
455
		$unused_portlist[$portname] = $portinfo;
456
	}
457
}
458

    
459
include("head.inc");
460

    
461
if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
462
	if ($_POST) {
463
		if ($rebootingnow) {
464
			$savemsg = gettext("The system is now rebooting.  Please wait.");
465
		} else {
466
			$savemsg = gettext("Reboot is needed. Please apply the settings in order to reboot.");
467
		}
468
	} else {
469
		$savemsg = gettext("Interface mismatch detected.  Please resolve the mismatch and click 'Apply changes'.  The firewall will reboot afterwards.");
470
	}
471
}
472

    
473
if (file_exists("/tmp/reload_interfaces")) {
474
	echo "<p>\n";
475
	print_info_box_np(gettext("The interface configuration has been changed.<br />You must apply the changes in order for them to take effect."));
476
	echo "<br /></p>\n";
477
} elseif ($savemsg) {
478
	print_info_box($savemsg);
479
}
480

    
481
pfSense_handle_custom_code("/usr/local/pkg/interfaces_assign/pre_input_errors");
482

    
483
if ($input_errors)
484
	print_input_errors($input_errors);
485

    
486
$tab_array = array();
487
$tab_array[0] = array(gettext("Interface assignments"), true, "interfaces_assign.php");
488
$tab_array[1] = array(gettext("Interface Groups"), false, "interfaces_groups.php");
489
$tab_array[2] = array(gettext("Wireless"), false, "interfaces_wireless.php");
490
$tab_array[3] = array(gettext("VLANs"), false, "interfaces_vlan.php");
491
$tab_array[4] = array(gettext("QinQs"), false, "interfaces_qinq.php");
492
$tab_array[5] = array(gettext("PPPs"), false, "interfaces_ppps.php");
493
$tab_array[7] = array(gettext("GRE"), false, "interfaces_gre.php");
494
$tab_array[8] = array(gettext("GIF"), false, "interfaces_gif.php");
495
$tab_array[9] = array(gettext("Bridges"), false, "interfaces_bridge.php");
496
$tab_array[10] = array(gettext("LAGG"), false, "interfaces_lagg.php");
497
display_top_tabs($tab_array);
498
?>
499
<form action="interfaces_assign.php" method="post">
500
	<div class="table-responsive">
501
	<table class="table table-striped table-hover">
502
	<thead>
503
		<tr>
504
			<th><?=gettext("Interface")?></th>
505
			<th><?=gettext("Network port")?></th>
506
		</tr>
507
	</thead>
508
	<tbody>
509
<?php
510
	foreach ($config['interfaces'] as $ifname => $iface):
511
		if ($iface['descr'])
512
			$ifdescr = $iface['descr'];
513
		else
514
			$ifdescr = strtoupper($ifname);
515
?>
516
		<tr>
517
			<td><a href="/interfaces.php?if=<?=$ifname?>"><?=$ifdescr?></a></td>
518
			<td>
519
				<select name="<?=$ifname?>" id="<?=$ifname?>" class="form-control">
520
<?php foreach ($portlist as $portname => $portinfo):?>
521
					<option value="<?=$portname?>" <?=($portname == $iface['if']) ? ' selected="selected"': ''?>>
522
						<?=interface_assign_description($portinfo, $portname)?>
523
					</option>
524
<?php endforeach;?>
525
				</select>
526
			</td>
527
			<td>
528
<?php if ($ifname != 'wan'):?>
529
				<input type="submit" name="del[<?=$ifname?>]" class="btn btn-danger" value="<?=gettext("delete interface")?>"/>
530
<?php endif;?>
531
			</td>
532
		</tr>
533
<?php endforeach;
534
	if (count($config['interfaces']) < count($portlist)):
535
?>
536
		<tr>
537
			<th>
538
				<?=gettext("Available network ports:")?>
539
			</th>
540
			<td>
541
				<select name="if_add" id="if_add" class="form-control">
542
<?php foreach ($unused_portlist as $portname => $portinfo):?>
543
					<option value="<?=$portname?>" <?=($portname == $iface['if']) ? ' selected="selected"': ''?>>
544
						<?=interface_assign_description($portinfo, $portname)?>
545
					</option>
546
<?php endforeach;?>
547
				</select>
548
			</td>
549
			<td>
550
				<input type="submit" name="add" title="<?=gettext("add selected interface")?>" value="add interface" class="btn btn-success" />
551
			</td>
552
		</tr>
553
<?php endif;?>
554
		</tbody>
555
	</table>
556
	</div>
557

    
558
	<input name="Submit" type="submit" class="btn btn-default" value="<?=gettext("Save")?>" /><br /><br />
559
</form>
560

    
561
<p class="alert alert-info"><?=gettext("Interfaces that are configured as members of a lagg(4) interface will not be shown.")?></p>
562

    
563
<?php include("foot.inc")?>
(84-84/235)