Project

General

Profile

Download (18.6 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 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
//$timealla = microtime(true);
35

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

    
39
require_once("guiconfig.inc");
40
require_once("functions.inc");
41
require_once("filter.inc");
42
require_once("shaper.inc");
43
require_once("ipsec.inc");
44
require_once("vpn.inc");
45
require_once("captiveportal.inc");
46
require_once("rrd.inc");
47
require_once("interfaces_fast.inc");
48

    
49
global $friendlyifnames;
50

    
51
/*moved most gettext calls to here, we really don't want to be repeatedly calling gettext() within loops if it can be avoided.*/
52
$gettextArray = array('add'=>gettext('Add'),'addif'=>gettext('Add interface'),'delete'=>gettext('Delete'),'deleteif'=>gettext('Delete interface'),'edit'=>gettext('Edit'),'on'=>gettext('on'));
53

    
54
/*
55
	In this file, "port" refers to the physical port name,
56
	while "interface" refers to LAN, WAN, or OPTn.
57
*/
58

    
59
/* get list without VLAN interfaces */
60
$portlist = get_interface_list();
61

    
62
/*another *_fast function from interfaces_fast.inc. These functions are basically the same as the
63
ones they're named after, except they (usually) take an array and (always) return an array. This means that they only
64
need to be called once per script run, the returned array contains all the data necessary for repeated use */
65
$friendlyifnames = convert_real_interface_to_friendly_interface_name_fast();
66

    
67
/* add wireless clone interfaces */
68
if (is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
69
	foreach ($config['wireless']['clone'] as $clone) {
70
		$portlist[$clone['cloneif']] = $clone;
71
		$portlist[$clone['cloneif']]['iswlclone'] = true;
72
	}
73
}
74

    
75
/* add VLAN interfaces */
76
if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
77
	//$timea = microtime(true);
78
	foreach ($config['vlans']['vlan'] as $vlan) {
79
		$portlist[$vlan['vlanif']] = $vlan;
80
		$portlist[$vlan['vlanif']]['isvlan'] = true;
81
	}
82
}
83

    
84
/* add Bridge interfaces */
85
if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
86
	foreach ($config['bridges']['bridged'] as $bridge) {
87
		$portlist[$bridge['bridgeif']] = $bridge;
88
		$portlist[$bridge['bridgeif']]['isbridge'] = true;
89
	}
90
}
91

    
92
/* add GIF interfaces */
93
if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
94
	foreach ($config['gifs']['gif'] as $gif) {
95
		$portlist[$gif['gifif']] = $gif;
96
		$portlist[$gif['gifif']]['isgif'] = true;
97
	}
98
}
99

    
100
/* add GRE interfaces */
101
if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
102
	foreach ($config['gres']['gre'] as $gre) {
103
		$portlist[$gre['greif']] = $gre;
104
		$portlist[$gre['greif']]['isgre'] = true;
105
	}
106
}
107

    
108
/* add LAGG interfaces */
109
if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
110
	foreach ($config['laggs']['lagg'] as $lagg) {
111
		$portlist[$lagg['laggif']] = $lagg;
112
		$portlist[$lagg['laggif']]['islagg'] = true;
113
		/* LAGG members cannot be assigned */
114
		$lagifs = explode(',', $lagg['members']);
115
		foreach ($lagifs as $lagif) {
116
			if (isset($portlist[$lagif])) {
117
				unset($portlist[$lagif]);
118
			}
119
		}
120
	}
121
}
122

    
123
/* add QinQ interfaces */
124
if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
125
	foreach ($config['qinqs']['qinqentry'] as $qinq) {
126
		$portlist["{$qinq['vlanif']}"]['descr'] = "VLAN {$qinq['tag']} on {$qinq['if']}";
127
		$portlist["{$qinq['vlanif']}"]['isqinq'] = true;
128
		/* QinQ members */
129
		$qinqifs = explode(' ', $qinq['members']);
130
		foreach ($qinqifs as $qinqif) {
131
			$portlist["{$qinq['vlanif']}.{$qinqif}"]['descr'] = "QinQ {$qinqif} on VLAN {$qinq['tag']} on {$qinq['if']}";
132
			$portlist["{$qinq['vlanif']}.{$qinqif}"]['isqinq'] = true;
133
		}
134
	}
135
}
136

    
137
/* add PPP interfaces */
138
if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
139
	foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
140
		$portname = $ppp['if'];
141
		$portlist[$portname] = $ppp;
142
		$portlist[$portname]['isppp'] = true;
143
		$ports_base = basename($ppp['ports']);
144
		if (isset($ppp['descr'])) {
145
			$portlist[$portname]['descr'] = strtoupper($ppp['if']). "({$ports_base}) - {$ppp['descr']}";
146
		} else if (isset($ppp['username'])) {
147
			$portlist[$portname]['descr'] = strtoupper($ppp['if']). "({$ports_base}) - {$ppp['username']}";
148
		} else {
149
			$portlist[$portname]['descr'] = strtoupper($ppp['if']). "({$ports_base})";
150
		}
151
	}
152
}
153

    
154
$ovpn_descrs = array();
155
if (is_array($config['openvpn'])) {
156
	if (is_array($config['openvpn']['openvpn-server'])) {
157
		foreach ($config['openvpn']['openvpn-server'] as $s) {
158
			$portname = "ovpns{$s['vpnid']}";
159
			$portlist[$portname] = $s;
160
			$ovpn_descrs[$s['vpnid']] = $s['description'];
161
		}
162
	}
163
	if (is_array($config['openvpn']['openvpn-client'])) {
164
		foreach ($config['openvpn']['openvpn-client'] as $c) {
165
			$portname = "ovpnc{$c['vpnid']}";
166
			$portlist[$portname] = $c;
167
			$ovpn_descrs[$c['vpnid']] = $c['description'];
168
		}
169
	}
170
}
171

    
172
global $ipsec_descrs;
173
$ipsec_descrs = interface_ipsec_vti_list_all();
174
foreach ($ipsec_descrs as $ifname => $ifdescr) {
175
	$portlist[$ifname] = array('descr' => $ifdescr);
176
}
177

    
178

    
179
$ifdescrs = interface_assign_description_fast($portlist,$friendlyifnames);
180

    
181
if (isset($_REQUEST['add']) && isset($_REQUEST['if_add'])) {
182
	/* Be sure this port is not being used */
183
	$portused = false;
184
	foreach ($config['interfaces'] as $ifname => $ifdata) {
185
		if ($ifdata['if'] == $_REQUEST['if_add']) {
186
			$portused = true;
187
			break;
188
		}
189
	}
190

    
191
	if ($portused === false) {
192
		/* find next free optional interface number */
193
		if (!$config['interfaces']['lan']) {
194
			$newifname = "lan";
195
			$descr = "LAN";
196
		} else {
197
			for ($i = 1; $i <= count($config['interfaces']); $i++) {
198
				if (!$config['interfaces']["opt{$i}"]) {
199
					break;
200
				}
201
			}
202
			$newifname = 'opt' . $i;
203
			$descr = "OPT" . $i;
204
		}
205

    
206
		$config['interfaces'][$newifname] = array();
207
		$config['interfaces'][$newifname]['descr'] = $descr;
208
		$config['interfaces'][$newifname]['if'] = $_POST['if_add'];
209
		if (preg_match($g['wireless_regex'], $_POST['if_add'])) {
210
			$config['interfaces'][$newifname]['wireless'] = array();
211
			interface_sync_wireless_clones($config['interfaces'][$newifname], false);
212
		}
213

    
214

    
215
		uksort($config['interfaces'], "compare_interface_friendly_names");
216

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

    
220
		write_config();
221

    
222
		$action_msg = gettext("Interface has been added.");
223
		$class = "success";
224
	}
225

    
226
} else if (isset($_POST['apply'])) {
227
	if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
228
		system_reboot();
229
		$rebootingnow = true;
230
	} else {
231
		write_config();
232

    
233
		$changes_applied = true;
234
		$retval = 0;
235
		$retval |= filter_configure();
236
	}
237

    
238
} else if (isset($_POST['Submit'])) {
239

    
240
	unset($input_errors);
241

    
242
	/* input validation */
243

    
244
	/* Build a list of the port names so we can see how the interfaces map */
245
	$portifmap = array();
246
	foreach ($portlist as $portname => $portinfo) {
247
		$portifmap[$portname] = array();
248
	}
249

    
250
	/* Go through the list of ports selected by the user,
251
	build a list of port-to-interface mappings in portifmap */
252
	foreach ($_POST as $ifname => $ifport) {
253
		if (($ifname == 'lan') || ($ifname == 'wan') || (substr($ifname, 0, 3) == 'opt')) {
254
			if (array_key_exists($ifport, $portlist)) {
255
				$portifmap[$ifport][] = strtoupper($ifname);
256
			} else {
257
				$input_errors[] = sprintf(gettext('Cannot set port %1$s because the submitted interface does not exist.'), $ifname);
258
			}
259
		}
260
	}
261

    
262
	/* Deliver error message for any port with more than one assignment */
263
	foreach ($portifmap as $portname => $ifnames) {
264
		if (count($ifnames) > 1) {
265
			$errstr = sprintf(gettext('Port %1$s '.
266
				' was assigned to %2$s' .
267
				' interfaces:'), $portname, count($ifnames));
268

    
269
			foreach ($portifmap[$portname] as $ifn) {
270
				$errstr .= " " . convert_friendly_interface_to_friendly_descr(strtolower($ifn)) . " (" . $ifn . ")";
271
			}
272

    
273
			$input_errors[] = $errstr;
274
		} else if (count($ifnames) == 1 && preg_match('/^bridge[0-9]/', $portname) && is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
275
			foreach ($config['bridges']['bridged'] as $bridge) {
276
				if ($bridge['bridgeif'] != $portname) {
277
					continue;
278
				}
279

    
280
				$members = explode(",", strtoupper($bridge['members']));
281
				foreach ($members as $member) {
282
					if ($member == $ifnames[0]) {
283
						$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);
284
						break;
285
					}
286
				}
287
			}
288
		}
289
	}
290

    
291
	if (is_array($config['vlans']['vlan'])) {
292
		foreach ($config['vlans']['vlan'] as $vlan) {
293
			if (does_interface_exist($vlan['if']) == false) {
294
				$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']);
295
			}
296
		}
297
	}
298

    
299
	if (!$input_errors) {
300
		/* No errors detected, so update the config */
301
		foreach ($_POST as $ifname => $ifport) {
302

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

    
305
				if (!is_array($ifport)) {
306
					$reloadif = false;
307
					if (!empty($config['interfaces'][$ifname]['if']) && $config['interfaces'][$ifname]['if'] <> $ifport) {
308
						interface_bring_down($ifname);
309
						/* Mark this to be reconfigured in any case. */
310
						$reloadif = true;
311
					}
312
					$config['interfaces'][$ifname]['if'] = $ifport;
313
					if (isset($portlist[$ifport]['isppp'])) {
314
						$config['interfaces'][$ifname]['ipaddr'] = $portlist[$ifport]['type'];
315
					}
316

    
317
					if (substr($ifport, 0, 3) == 'gre' || substr($ifport, 0, 3) == 'gif') {
318
						unset($config['interfaces'][$ifname]['ipaddr']);
319
						unset($config['interfaces'][$ifname]['subnet']);
320
						unset($config['interfaces'][$ifname]['ipaddrv6']);
321
						unset($config['interfaces'][$ifname]['subnetv6']);
322
					}
323

    
324
					/* check for wireless interfaces, set or clear ['wireless'] */
325
					if (preg_match($g['wireless_regex'], $ifport)) {
326
						if (!is_array($config['interfaces'][$ifname]['wireless'])) {
327
							$config['interfaces'][$ifname]['wireless'] = array();
328
						}
329
					} else {
330
						unset($config['interfaces'][$ifname]['wireless']);
331
					}
332

    
333
					/* make sure there is a descr for all interfaces */
334
					if (!isset($config['interfaces'][$ifname]['descr'])) {
335
						$config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
336
					}
337

    
338
					if ($reloadif == true) {
339
						if (preg_match($g['wireless_regex'], $ifport)) {
340
							interface_sync_wireless_clones($config['interfaces'][$ifname], false);
341
						}
342
						/* Reload all for the interface. */
343
						interface_configure($ifname, true);
344
					}
345
				}
346
			}
347
		}
348
		write_config();
349

    
350
		enable_rrd_graphing();
351
	}
352
} else {
353
	unset($delbtn);
354
	if (!empty($_POST['del'])) {
355
		$delbtn = key($_POST['del']);
356
	}
357

    
358
	if (isset($delbtn)) {
359
		$id = $delbtn;
360

    
361
		if (link_interface_to_group($id)) {
362
			$input_errors[] = gettext("The interface is part of a group. Please remove it from the group to continue");
363
		} else if (link_interface_to_bridge($id)) {
364
			$input_errors[] = gettext("The interface is part of a bridge. Please remove it from the bridge to continue");
365
		} else if (link_interface_to_gre($id)) {
366
			$input_errors[] = gettext("The interface is part of a gre tunnel. Please delete the tunnel to continue");
367
		} else if (link_interface_to_gif($id)) {
368
			$input_errors[] = gettext("The interface is part of a gif tunnel. Please delete the tunnel to continue");
369
		} else if (interface_has_queue($id)) {
370
			$input_errors[] = gettext("The interface has a traffic shaper queue configured.\nPlease remove all queues on the interface to continue.");
371
		} else {
372
			unset($config['interfaces'][$id]['enable']);
373
			$realid = get_real_interface($id);
374
			interface_bring_down($id);   /* down the interface */
375

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

    
378
			if (is_array($config['dhcpd']) && is_array($config['dhcpd'][$id])) {
379
				unset($config['dhcpd'][$id]);
380
				services_dhcpd_configure('inet');
381
			}
382

    
383
			if (is_array($config['dhcpdv6']) && is_array($config['dhcpdv6'][$id])) {
384
				unset($config['dhcpdv6'][$id]);
385
				services_dhcpd_configure('inet6');
386
			}
387

    
388
			if (count($config['filter']['rule']) > 0) {
389
				foreach ($config['filter']['rule'] as $x => $rule) {
390
					if ($rule['interface'] == $id) {
391
						unset($config['filter']['rule'][$x]);
392
					}
393
				}
394
			}
395
			if (is_array($config['nat']['rule']) && count($config['nat']['rule']) > 0) {
396
				foreach ($config['nat']['rule'] as $x => $rule) {
397
					if ($rule['interface'] == $id) {
398
						unset($config['nat']['rule'][$x]['interface']);
399
					}
400
				}
401
			}
402

    
403
			write_config();
404

    
405
			/* If we are in firewall/routing mode (not single interface)
406
			 * then ensure that we are not running DHCP on the wan which
407
			 * will make a lot of ISP's unhappy.
408
			 */
409
			if ($config['interfaces']['lan'] && $config['dhcpd']['wan']) {
410
				unset($config['dhcpd']['wan']);
411
			}
412

    
413
			link_interface_to_vlans($realid, "update");
414

    
415
			$action_msg = gettext("Interface has been deleted.");
416
			$class = "success";
417
		}
418
	}
419
}
420

    
421
/* Create a list of unused ports */
422
$unused_portlist = array();
423
$portArray = array_keys($portlist);
424

    
425
$ifaceArray = array_column($config['interfaces'],'if');
426
$unused = array_diff($portArray,$ifaceArray);
427
$unused = array_flip($unused);
428
$unused_portlist = array_intersect_key($portlist,$unused);//*/
429
unset($unused,$portArray,$ifaceArray);
430

    
431
include("head.inc");
432

    
433
if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
434
	if ($_POST) {
435
		if ($rebootingnow) {
436
			$action_msg = gettext("The system is now rebooting. Please wait.");
437
			$class = "success";
438
		} else {
439
			$applymsg = gettext("Reboot is needed. Please apply the settings in order to reboot.");
440
			$class = "warning";
441
		}
442
	} else {
443
		$action_msg = gettext("Interface mismatch detected. Please resolve the mismatch, save and then click 'Apply Changes'. The firewall will reboot afterwards.");
444
		$class = "warning";
445
	}
446
}
447

    
448
if (file_exists("/tmp/reload_interfaces")) {
449
	echo "<p>\n";
450
	print_apply_box(gettext("The interface configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect."));
451
	echo "<br /></p>\n";
452
} elseif ($applymsg) {
453
	print_apply_box($applymsg);
454
} elseif ($action_msg) {
455
	print_info_box($action_msg, $class);
456
} elseif ($changes_applied) {
457
	print_apply_result_box($retval);
458
}
459

    
460
pfSense_handle_custom_code("/usr/local/pkg/interfaces_assign/pre_input_errors");
461

    
462
if ($input_errors) {
463
	print_input_errors($input_errors);
464
}
465

    
466
$tab_array = array();
467
$tab_array[] = array(gettext("Interface Assignments"), true, "interfaces_assign.php");
468
$tab_array[] = array(gettext("Interface Groups"), false, "interfaces_groups.php");
469
$tab_array[] = array(gettext("Wireless"), false, "interfaces_wireless.php");
470
$tab_array[] = array(gettext("VLANs"), false, "interfaces_vlan.php");
471
$tab_array[] = array(gettext("QinQs"), false, "interfaces_qinq.php");
472
$tab_array[] = array(gettext("PPPs"), false, "interfaces_ppps.php");
473
$tab_array[] = array(gettext("GREs"), false, "interfaces_gre.php");
474
$tab_array[] = array(gettext("GIFs"), false, "interfaces_gif.php");
475
$tab_array[] = array(gettext("Bridges"), false, "interfaces_bridge.php");
476
$tab_array[] = array(gettext("LAGGs"), false, "interfaces_lagg.php");
477
display_top_tabs($tab_array);
478

    
479
/*Generate the port select box only once.
480
Not indenting the HTML to produce smaller code
481
and faster page load times */
482

    
483
$portselect='';
484
foreach ($portlist as $portname => $portinfo) {
485
	$portselect.='<option value="'.$portname.'"';
486
	$portselect.=">".$ifdescrs[$portname]."</option>\n";
487
}
488

    
489
?>
490
<form action="interfaces_assign.php" method="post">
491
	<div class="table-responsive">
492
	<table class="table table-striped table-hover">
493
	<thead>
494
		<tr>
495
			<th><?=gettext("Interface")?></th>
496
			<th><?=gettext("Network port")?></th>
497
			<th>&nbsp;</th>
498
		</tr>
499
	</thead>
500
	<tbody>
501
<?php
502
	$i=0;
503
	foreach ($config['interfaces'] as $ifname => $iface):
504
		if ($iface['descr']) {
505
			$ifdescr = $iface['descr'];
506
		} else {
507
			$ifdescr = strtoupper($ifname);
508
		}
509
?>
510
		<tr>
511
			<td><a href="/interfaces.php?if=<?=$ifname?>"><?=$ifdescr?></a></td>
512
			<td>
513
				<select name="<?=$ifname?>" id="<?=$ifname?>" class="form-control">
514
<?php
515
/*port select menu generation loop replaced with pre-prepared select menu to reduce page generation time */
516
echo str_replace('value="'.$iface['if'].'">','value="'.$iface['if'].'" selected>',$portselect);
517
?>
518
				</select>
519
			</td>
520
			<td>
521
<?php if ($ifname != 'wan'):?>
522
				<button type="submit" name="del[<?=$ifname?>]" class="btn btn-danger btn-sm" title="<?=$gettextArray['deleteif']?>">
523
					<i class="fa fa-trash icon-embed-btn"></i>
524
					<?=$gettextArray["delete"]?>
525
				</button>
526
<?php endif;?>
527
			</td>
528
		</tr>
529
<?php $i++;
530
endforeach;
531
	if (count($config['interfaces']) < count($portlist)):
532
?>
533
		<tr>
534
			<th>
535
				<?=gettext("Available network ports:")?>
536
			</th>
537
			<td>
538
				<select name="if_add" id="if_add" class="form-control">
539
<?php
540
/* HTML not indented to save on transmission/render time */
541
foreach ($unused_portlist as $portname => $portinfo):?>
542
<option value="<?=$portname?>" <?=($portname == $iface['if']) ? ' selected': ''?>><?=$ifdescrs[$portname]?></option>
543
<?php endforeach;
544
?>
545
				</select>
546
			</td>
547
			<td>
548
				<button type="submit" name="add" title="<?=gettext("Add selected interface")?>" value="add interface" class="btn btn-success btn-sm" >
549
					<i class="fa fa-plus icon-embed-btn"></i>
550
					<?=$gettextArray["add"]?>
551
				</button>
552
			</td>
553
		</tr>
554
<?php endif;?>
555
		</tbody>
556
	</table>
557
	</div>
558

    
559
	<button name="Submit" type="submit" class="btn btn-primary" value="<?=gettext('Save')?>"><i class="fa fa-save icon-embed-btn"></i><?=gettext('Save')?></button>
560
</form>
561
<br />
562

    
563
<?php
564
print_info_box(gettext("Interfaces that are configured as members of a lagg(4) interface will not be shown.") .
565
    '<br/><br/>' .
566
    gettext("Wireless interfaces must be created on the Wireless tab before they can be assigned."), 'info', false);
567
?>
568

    
569
<?php include("foot.inc")?>
(72-72/234)