Project

General

Profile

Download (17.9 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
			$ovpn_descrs[$s['vpnid']] = $s['description'];
200
		}
201
	}
202
	if (is_array($config['openvpn']['openvpn-client'])) {
203
		foreach ($config['openvpn']['openvpn-client'] as $c) {
204
			$ovpn_descrs[$c['vpnid']] = $c['description'];
205
		}
206
	}
207
}
208

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

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

    
234
		$config['interfaces'][$newifname] = array();
235
		$config['interfaces'][$newifname]['descr'] = $descr;
236
		$config['interfaces'][$newifname]['if'] = $_POST['if_add'];
237
		if (preg_match($g['wireless_regex'], $_POST['if_add'])) {
238
			$config['interfaces'][$newifname]['wireless'] = array();
239
			interface_sync_wireless_clones($config['interfaces'][$newifname], false);
240
		}
241

    
242
		uksort($config['interfaces'], "compare_interface_friendly_names");
243

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

    
247
		write_config();
248

    
249
		$savemsg = gettext("Interface has been added.");
250
	}
251

    
252
} else if (isset($_POST['apply'])) {
253
	if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
254
		system_reboot();
255
		$rebootingnow = true;
256
	} else {
257
		write_config();
258

    
259
		$retval = filter_configure();
260
		$savemsg = get_std_save_message($retval);
261

    
262
		if (stristr($retval, "error") <> true) {
263
			$savemsg = get_std_save_message($retval);
264
		} else {
265
			$savemsg = $retval;
266
		}
267
	}
268

    
269
} else if (isset($_POST['Submit'])) {
270

    
271
	unset($input_errors);
272

    
273
	/* input validation */
274

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

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

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

    
296
			foreach ($portifmap[$portname] as $ifn) {
297
				$errstr .= " " . convert_friendly_interface_to_friendly_descr(strtolower($ifn)) . " (" . $ifn . ")";
298
			}
299

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

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

    
318
	if (is_array($config['vlans']['vlan'])) {
319
		foreach ($config['vlans']['vlan'] as $vlan) {
320
			if (does_interface_exist($vlan['if']) == false) {
321
				$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.";
322
			}
323
		}
324
	}
325

    
326
	if (!$input_errors) {
327
		/* No errors detected, so update the config */
328
		foreach ($_POST as $ifname => $ifport) {
329

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

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

    
344
					if (substr($ifport, 0, 3) == 'gre' || substr($ifport, 0, 3) == 'gif') {
345
						unset($config['interfaces'][$ifname]['ipaddr']);
346
						unset($config['interfaces'][$ifname]['subnet']);
347
						unset($config['interfaces'][$ifname]['ipaddrv6']);
348
						unset($config['interfaces'][$ifname]['subnetv6']);
349
					}
350

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

    
360
					/* make sure there is a descr for all interfaces */
361
					if (!isset($config['interfaces'][$ifname]['descr'])) {
362
						$config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
363
					}
364

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

    
376
		write_config();
377

    
378
		enable_rrd_graphing();
379
	}
380
} else {
381
	unset($delbtn);
382
	if (!empty($_POST['del']))
383
		$delbtn = key($_POST['del']);
384

    
385
	if (isset($delbtn)) {
386
		$id = $delbtn;
387

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

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

    
403
			if (is_array($config['dhcpd']) && is_array($config['dhcpd'][$id])) {
404
				unset($config['dhcpd'][$id]);
405
				services_dhcpd_configure();
406
			}
407

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

    
423
			write_config();
424

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

    
433
			link_interface_to_vlans($realid, "update");
434

    
435
			$savemsg = gettext("Interface has been deleted.");
436
		}
437
	}
438
}
439

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

    
455
include("head.inc");
456

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

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

    
477
pfSense_handle_custom_code("/usr/local/pkg/interfaces_assign/pre_input_errors");
478

    
479
if ($input_errors)
480
	print_input_errors($input_errors);
481

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

    
554
	<input name="Submit" type="submit" class="btn btn-default" value="<?=gettext("Save")?>" /><br /><br />
555
</form>
556

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

    
559
<?php include("foot.inc")?>
(84-84/238)