Project

General

Profile

Download (18.5 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-2018 Rubicon Communications, LLC (Netgate)
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
		$descr .= " (" . $portinfo['mac'] . ")";
82
		if ($portinfo['descr']) {
83
			$descr .= " - " . $portinfo['descr'];
84
		}
85
	} elseif ($portinfo['isqinq']) {
86
		$descr = $portinfo['descr'];
87
	} elseif (substr($portname, 0, 4) == 'ovpn') {
88
		$descr = $portname . " (" . $ovpn_descrs[substr($portname, 5)] . ")";
89
	} else {
90
		$descr = $portname . " (" . $portinfo['mac'] . ")";
91
	}
92

    
93
	return htmlspecialchars($descr);
94
}
95

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

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

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

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

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

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

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

    
144
/* add LAGG interfaces */
145
$lagglist = get_lagg_interface_list();
146
$portlist = array_merge($portlist, $lagglist);
147
foreach ($lagglist as $laggif => $lagg) {
148
	/* LAGG members cannot be assigned */
149
	$laggmembers = explode(',', $lagg['members']);
150
	foreach ($laggmembers as $lagm) {
151
		if (isset($portlist[$lagm])) {
152
			unset($portlist[$lagm]);
153
		}
154
	}
155
}
156

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

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

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

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

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

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

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

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

    
244
		write_config();
245

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

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

    
257
		$changes_applied = true;
258
		$retval = 0;
259
		$retval |= filter_configure();
260
	}
261

    
262
} else if (isset($_POST['Submit'])) {
263

    
264
	unset($input_errors);
265

    
266
	/* input validation */
267

    
268
	/* Build a list of the port names so we can see how the interfaces map */
269
	$portifmap = array();
270
	foreach ($portlist as $portname => $portinfo) {
271
		$portifmap[$portname] = array();
272
	}
273

    
274
	/* Go through the list of ports selected by the user,
275
	build a list of port-to-interface mappings in portifmap */
276
	foreach ($_POST as $ifname => $ifport) {
277
		if (($ifname == 'lan') || ($ifname == 'wan') || (substr($ifname, 0, 3) == 'opt')) {
278
			$portifmap[$ifport][] = strtoupper($ifname);
279
		}
280
	}
281

    
282
	/* Deliver error message for any port with more than one assignment */
283
	foreach ($portifmap as $portname => $ifnames) {
284
		if (count($ifnames) > 1) {
285
			$errstr = sprintf(gettext('Port %1$s '.
286
				' was assigned to %2$s' .
287
				' interfaces:'), $portname, count($ifnames));
288

    
289
			foreach ($portifmap[$portname] as $ifn) {
290
				$errstr .= " " . convert_friendly_interface_to_friendly_descr(strtolower($ifn)) . " (" . $ifn . ")";
291
			}
292

    
293
			$input_errors[] = $errstr;
294
		} else if (count($ifnames) == 1 && preg_match('/^bridge[0-9]/', $portname) && is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
295
			foreach ($config['bridges']['bridged'] as $bridge) {
296
				if ($bridge['bridgeif'] != $portname) {
297
					continue;
298
				}
299

    
300
				$members = explode(",", strtoupper($bridge['members']));
301
				foreach ($members as $member) {
302
					if ($member == $ifnames[0]) {
303
						$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);
304
						break;
305
					}
306
				}
307
			}
308
		}
309
	}
310

    
311
	if (is_array($config['vlans']['vlan'])) {
312
		foreach ($config['vlans']['vlan'] as $vlan) {
313
			if (does_interface_exist($vlan['if']) == false) {
314
				$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']);
315
			}
316
		}
317
	}
318

    
319
	if (!$input_errors) {
320
		/* No errors detected, so update the config */
321
		foreach ($_POST as $ifname => $ifport) {
322

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

    
325
				if (!is_array($ifport)) {
326
					$reloadif = false;
327
					if (!empty($config['interfaces'][$ifname]['if']) && $config['interfaces'][$ifname]['if'] <> $ifport) {
328
						interface_bring_down($ifname);
329
						/* Mark this to be reconfigured in any case. */
330
						$reloadif = true;
331
					}
332
					$config['interfaces'][$ifname]['if'] = $ifport;
333
					if (isset($portlist[$ifport]['isppp'])) {
334
						$config['interfaces'][$ifname]['ipaddr'] = $portlist[$ifport]['type'];
335
					}
336

    
337
					if (substr($ifport, 0, 3) == 'gre' || substr($ifport, 0, 3) == 'gif') {
338
						unset($config['interfaces'][$ifname]['ipaddr']);
339
						unset($config['interfaces'][$ifname]['subnet']);
340
						unset($config['interfaces'][$ifname]['ipaddrv6']);
341
						unset($config['interfaces'][$ifname]['subnetv6']);
342
					}
343

    
344
					/* check for wireless interfaces, set or clear ['wireless'] */
345
					if (preg_match($g['wireless_regex'], $ifport)) {
346
						if (!is_array($config['interfaces'][$ifname]['wireless'])) {
347
							$config['interfaces'][$ifname]['wireless'] = array();
348
						}
349
					} else {
350
						unset($config['interfaces'][$ifname]['wireless']);
351
					}
352

    
353
					/* make sure there is a descr for all interfaces */
354
					if (!isset($config['interfaces'][$ifname]['descr'])) {
355
						$config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
356
					}
357

    
358
					if ($reloadif == true) {
359
						if (preg_match($g['wireless_regex'], $ifport)) {
360
							interface_sync_wireless_clones($config['interfaces'][$ifname], false);
361
						}
362
						/* Reload all for the interface. */
363
						interface_configure($ifname, true);
364
					}
365
				}
366
			}
367
		}
368

    
369
		write_config();
370

    
371
		enable_rrd_graphing();
372
	}
373
} else {
374
	unset($delbtn);
375
	if (!empty($_POST['del'])) {
376
		$delbtn = key($_POST['del']);
377
	}
378

    
379
	if (isset($delbtn)) {
380
		$id = $delbtn;
381

    
382
		if (link_interface_to_group($id)) {
383
			$input_errors[] = gettext("The interface is part of a group. Please remove it from the group to continue");
384
		} else if (link_interface_to_bridge($id)) {
385
			$input_errors[] = gettext("The interface is part of a bridge. Please remove it from the bridge to continue");
386
		} else if (link_interface_to_gre($id)) {
387
			$input_errors[] = gettext("The interface is part of a gre tunnel. Please delete the tunnel to continue");
388
		} else if (link_interface_to_gif($id)) {
389
			$input_errors[] = gettext("The interface is part of a gif tunnel. Please delete the tunnel to continue");
390
		} else if (interface_has_queue($id)) {
391
			$input_errors[] = gettext("The interface has a traffic shaper queue configured.\nPlease remove all queues on the interface to continue.");
392
		} else {
393
			unset($config['interfaces'][$id]['enable']);
394
			$realid = get_real_interface($id);
395
			interface_bring_down($id);   /* down the interface */
396

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

    
399
			if (is_array($config['dhcpd']) && is_array($config['dhcpd'][$id])) {
400
				unset($config['dhcpd'][$id]);
401
				services_dhcpd_configure('inet');
402
			}
403

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

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

    
424
			write_config();
425

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

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

    
436
			$action_msg = gettext("Interface has been deleted.");
437
			$class = "success";
438
		}
439
	}
440
}
441

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

    
457
include("head.inc");
458

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

    
474
if (file_exists("/tmp/reload_interfaces")) {
475
	echo "<p>\n";
476
	print_apply_box(gettext("The interface configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect."));
477
	echo "<br /></p>\n";
478
} elseif ($applymsg) {
479
	print_apply_box($applymsg);
480
} elseif ($action_msg) {
481
	print_info_box($action_msg, $class);
482
} elseif ($changes_applied) {
483
	print_apply_result_box($retval);
484
}
485

    
486
pfSense_handle_custom_code("/usr/local/pkg/interfaces_assign/pre_input_errors");
487

    
488
if ($input_errors) {
489
	print_input_errors($input_errors);
490
}
491

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

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

    
576
<?php
577
print_info_box(gettext("Interfaces that are configured as members of a lagg(4) interface will not be shown.") .
578
    '<br/><br/>' .
579
    gettext("Wireless interfaces must be created on the Wireless tab before they can be assigned."), 'info', false);
580
?>
581

    
582
<?php include("foot.inc")?>
(73-73/232)