Project

General

Profile

Download (18.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * interfaces_assign.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Electric Sheep Fencing, LLC
7
 * All rights reserved.
8
 *
9
 * originally based on m0n0wall (http://m0n0.ch/wall)
10
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
11
 * Written by Jim McBeath based on existing m0n0wall files
12
 * All rights reserved.
13
 *
14
 * Licensed under the Apache License, Version 2.0 (the "License");
15
 * you may not use this file except in compliance with the License.
16
 * You may obtain a copy of the License at
17
 *
18
 * http://www.apache.org/licenses/LICENSE-2.0
19
 *
20
 * Unless required by applicable law or agreed to in writing, software
21
 * distributed under the License is distributed on an "AS IS" BASIS,
22
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
 * See the License for the specific language governing permissions and
24
 * limitations under the License.
25
 */
26

    
27
##|+PRIV
28
##|*IDENT=page-interfaces-assignnetworkports
29
##|*NAME=Interfaces: Interface Assignments
30
##|*DESCR=Allow access to the 'Interfaces: Interface Assignments' page.
31
##|*MATCH=interfaces_assign.php*
32
##|-PRIV
33

    
34
$pgtitle = array(gettext("Interfaces"), gettext("Interface Assignments"));
35
$shortcut_section = "interfaces";
36

    
37
require_once("guiconfig.inc");
38
require_once("functions.inc");
39
require_once("filter.inc");
40
require_once("shaper.inc");
41
require_once("ipsec.inc");
42
require_once("vpn.inc");
43
require_once("captiveportal.inc");
44
require_once("rrd.inc");
45

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

    
92
	return htmlspecialchars($descr);
93
}
94

    
95
/*
96
	In this file, "port" refers to the physical port name,
97
	while "interface" refers to LAN, WAN, or OPTn.
98
*/
99

    
100
/* get list without VLAN interfaces */
101
$portlist = get_interface_list();
102

    
103
/* add wireless clone interfaces */
104
if (is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
105
	foreach ($config['wireless']['clone'] as $clone) {
106
		$portlist[$clone['cloneif']] = $clone;
107
		$portlist[$clone['cloneif']]['iswlclone'] = true;
108
	}
109
}
110

    
111
/* add VLAN interfaces */
112
if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
113
	foreach ($config['vlans']['vlan'] as $vlan) {
114
		$portlist[$vlan['vlanif']] = $vlan;
115
		$portlist[$vlan['vlanif']]['isvlan'] = true;
116
	}
117
}
118

    
119
/* add Bridge interfaces */
120
if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
121
	foreach ($config['bridges']['bridged'] as $bridge) {
122
		$portlist[$bridge['bridgeif']] = $bridge;
123
		$portlist[$bridge['bridgeif']]['isbridge'] = true;
124
	}
125
}
126

    
127
/* add GIF interfaces */
128
if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
129
	foreach ($config['gifs']['gif'] as $gif) {
130
		$portlist[$gif['gifif']] = $gif;
131
		$portlist[$gif['gifif']]['isgif'] = true;
132
	}
133
}
134

    
135
/* add GRE interfaces */
136
if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
137
	foreach ($config['gres']['gre'] as $gre) {
138
		$portlist[$gre['greif']] = $gre;
139
		$portlist[$gre['greif']]['isgre'] = true;
140
	}
141
}
142

    
143
/* add LAGG interfaces */
144
if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
145
	foreach ($config['laggs']['lagg'] as $lagg) {
146
		$portlist[$lagg['laggif']] = $lagg;
147
		$portlist[$lagg['laggif']]['islagg'] = true;
148
		/* LAGG members cannot be assigned */
149
		$lagifs = explode(',', $lagg['members']);
150
		foreach ($lagifs as $lagif) {
151
			if (isset($portlist[$lagif])) {
152
				unset($portlist[$lagif]);
153
			}
154
		}
155
	}
156
}
157

    
158
/* add QinQ interfaces */
159
if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
160
	foreach ($config['qinqs']['qinqentry'] as $qinq) {
161
		$portlist["{$qinq['vlanif']}"]['descr'] = "VLAN {$qinq['tag']} on {$qinq['if']}";
162
		$portlist["{$qinq['vlanif']}"]['isqinq'] = true;
163
		/* QinQ members */
164
		$qinqifs = explode(' ', $qinq['members']);
165
		foreach ($qinqifs as $qinqif) {
166
			$portlist["{$qinq['vlanif']}_{$qinqif}"]['descr'] = "QinQ {$qinqif} on VLAN {$qinq['tag']} on {$qinq['if']}";
167
			$portlist["{$qinq['vlanif']}_{$qinqif}"]['isqinq'] = true;
168
		}
169
	}
170
}
171

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

    
189
$ovpn_descrs = array();
190
if (is_array($config['openvpn'])) {
191
	if (is_array($config['openvpn']['openvpn-server'])) {
192
		foreach ($config['openvpn']['openvpn-server'] as $s) {
193
			$portname = "ovpns{$s['vpnid']}";
194
			$portlist[$portname] = $s;
195
			$ovpn_descrs[$s['vpnid']] = $s['description'];
196
		}
197
	}
198
	if (is_array($config['openvpn']['openvpn-client'])) {
199
		foreach ($config['openvpn']['openvpn-client'] as $c) {
200
			$portname = "ovpnc{$c['vpnid']}";
201
			$portlist[$portname] = $c;
202
			$ovpn_descrs[$c['vpnid']] = $c['description'];
203
		}
204
	}
205
}
206

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

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

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

    
240
		uksort($config['interfaces'], "compare_interface_friendly_names");
241

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

    
245
		write_config();
246

    
247
		$savemsg = gettext("Interface has been added.");
248
		$class = "success";
249
	}
250

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

    
258
		$retval = filter_configure();
259

    
260
		if (stristr($retval, "error") <> true) {
261
			$savemsg = get_std_save_message($retval);
262
			$class = "success";
263
		} else {
264
			$savemsg = $retval;
265
			$class = "danger";
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('Cannot set port %1$s to interface %2$s because this interface is a member of %3$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[] = sprintf(gettext('Vlan parent interface %1$s does not exist anymore so vlan id %2$s cannot be created please fix the issue before continuing.'), $vlan['if'], $vlan['tag']);
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

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

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

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

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

    
409
			if (is_array($config['dhcpdv6']) && is_array($config['dhcpdv6'][$id])) {
410
				unset($config['dhcpdv6'][$id]);
411
				services_dhcpdv6_configure();
412
			}
413

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

    
429
			write_config();
430

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

    
439
			link_interface_to_vlans($realid, "update");
440

    
441
			$savemsg = gettext("Interface has been deleted.");
442
			$class = "success";
443
		}
444
	}
445
}
446

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

    
462
include("head.inc");
463

    
464
if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
465
	if ($_POST) {
466
		if ($rebootingnow) {
467
			$savemsg = gettext("The system is now rebooting. Please wait.");
468
			$class = "success";
469
		} else {
470
			$applymsg = gettext("Reboot is needed. Please apply the settings in order to reboot.");
471
			$class = "warning";
472
		}
473
	} else {
474
		$savemsg = gettext("Interface mismatch detected. Please resolve the mismatch, save and then click 'Apply Changes'. The firewall will reboot afterwards.");
475
		$class = "warning";
476
	}
477
}
478

    
479
if (file_exists("/tmp/reload_interfaces")) {
480
	echo "<p>\n";
481
	print_apply_box(gettext("The interface configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect."));
482
	echo "<br /></p>\n";
483
} elseif ($applymsg) {
484
	print_apply_box($applymsg);
485
} elseif ($savemsg) {
486
	print_info_box($savemsg, $class);
487
}
488

    
489
pfSense_handle_custom_code("/usr/local/pkg/interfaces_assign/pre_input_errors");
490

    
491
if ($input_errors) {
492
	print_input_errors($input_errors);
493
}
494

    
495
$tab_array = array();
496
$tab_array[] = array(gettext("Interface Assignments"), true, "interfaces_assign.php");
497
$tab_array[] = array(gettext("Interface Groups"), false, "interfaces_groups.php");
498
$tab_array[] = array(gettext("Wireless"), false, "interfaces_wireless.php");
499
$tab_array[] = array(gettext("VLANs"), false, "interfaces_vlan.php");
500
$tab_array[] = array(gettext("QinQs"), false, "interfaces_qinq.php");
501
$tab_array[] = array(gettext("PPPs"), false, "interfaces_ppps.php");
502
$tab_array[] = array(gettext("GREs"), false, "interfaces_gre.php");
503
$tab_array[] = array(gettext("GIFs"), false, "interfaces_gif.php");
504
$tab_array[] = array(gettext("Bridges"), false, "interfaces_bridge.php");
505
$tab_array[] = array(gettext("LAGGs"), false, "interfaces_lagg.php");
506
display_top_tabs($tab_array);
507
?>
508
<form action="interfaces_assign.php" method="post">
509
	<div class="table-responsive">
510
	<table class="table table-striped table-hover">
511
	<thead>
512
		<tr>
513
			<th><?=gettext("Interface")?></th>
514
			<th><?=gettext("Network port")?></th>
515
			<th>&nbsp;</th>
516
		</tr>
517
	</thead>
518
	<tbody>
519
<?php
520
	foreach ($config['interfaces'] as $ifname => $iface):
521
		if ($iface['descr']) {
522
			$ifdescr = $iface['descr'];
523
		} else {
524
			$ifdescr = strtoupper($ifname);
525
		}
526
?>
527
		<tr>
528
			<td><a href="/interfaces.php?if=<?=$ifname?>"><?=$ifdescr?></a></td>
529
			<td>
530
				<select name="<?=$ifname?>" id="<?=$ifname?>" class="form-control">
531
<?php foreach ($portlist as $portname => $portinfo):?>
532
					<option value="<?=$portname?>" <?=($portname == $iface['if']) ? ' selected': ''?>>
533
						<?=interface_assign_description($portinfo, $portname)?>
534
					</option>
535
<?php endforeach;?>
536
				</select>
537
			</td>
538
			<td>
539
<?php if ($ifname != 'wan'):?>
540
				<button type="submit" name="del[<?=$ifname?>]" class="btn btn-danger btn-sm" title="<?=gettext("Delete interface")?>">
541
					<i class="fa fa-trash icon-embed-btn"></i>
542
					<?=gettext("Delete")?>
543
				</button>
544
<?php endif;?>
545
			</td>
546
		</tr>
547
<?php endforeach;
548
	if (count($config['interfaces']) < count($portlist)):
549
?>
550
		<tr>
551
			<th>
552
				<?=gettext("Available network ports:")?>
553
			</th>
554
			<td>
555
				<select name="if_add" id="if_add" class="form-control">
556
<?php foreach ($unused_portlist as $portname => $portinfo):?>
557
					<option value="<?=$portname?>" <?=($portname == $iface['if']) ? ' selected': ''?>>
558
						<?=interface_assign_description($portinfo, $portname)?>
559
					</option>
560
<?php endforeach;?>
561
				</select>
562
			</td>
563
			<td>
564
				<button type="submit" name="add" title="<?=gettext("Add selected interface")?>" value="add interface" class="btn btn-success btn-sm" >
565
					<i class="fa fa-plus icon-embed-btn"></i>
566
					<?=gettext("Add")?>
567
				</button>
568
			</td>
569
		</tr>
570
<?php endif;?>
571
		</tbody>
572
	</table>
573
	</div>
574

    
575
	<button name="Submit" type="submit" class="btn btn-primary" value="<?=gettext('Save')?>"><i class="fa fa-save icon-embed-btn"></i><?=gettext('Save')?></button>
576
</form>
577
<br />
578

    
579
<?php
580
print_info_box(gettext("Interfaces that are configured as members of a lagg(4) interface will not be shown."), 'info', false);
581
?>
582

    
583
<?php include("foot.inc")?>
(69-69/227)