Project

General

Profile

Download (20 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
 * Redistribution and use in source and binary forms, with or without
15
 * modification, are permitted provided that the following conditions are met:
16
 *
17
 * 1. Redistributions of source code must retain the above copyright notice,
18
 *    this list of conditions and the following disclaimer.
19
 *
20
 * 2. Redistributions in binary form must reproduce the above copyright
21
 *    notice, this list of conditions and the following disclaimer in
22
 *    the documentation and/or other materials provided with the
23
 *    distribution.
24
 *
25
 * 3. All advertising materials mentioning features or use of this software
26
 *    must display the following acknowledgment:
27
 *    "This product includes software developed by the pfSense Project
28
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
29
 *
30
 * 4. The names "pfSense" and "pfSense Project" must not be used to
31
 *    endorse or promote products derived from this software without
32
 *    prior written permission. For written permission, please contact
33
 *    coreteam@pfsense.org.
34
 *
35
 * 5. Products derived from this software may not be called "pfSense"
36
 *    nor may "pfSense" appear in their names without prior written
37
 *    permission of the Electric Sheep Fencing, LLC.
38
 *
39
 * 6. Redistributions of any form whatsoever must retain the following
40
 *    acknowledgment:
41
 *
42
 * "This product includes software developed by the pfSense Project
43
 * for use in the pfSense software distribution (http://www.pfsense.org/).
44
 *
45
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
46
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
49
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56
 * OF THE POSSIBILITY OF SUCH DAMAGE.
57
 */
58

    
59
##|+PRIV
60
##|*IDENT=page-interfaces-assignnetworkports
61
##|*NAME=Interfaces: Interface Assignments
62
##|*DESCR=Allow access to the 'Interfaces: Interface Assignments' page.
63
##|*MATCH=interfaces_assign.php*
64
##|-PRIV
65

    
66
$pgtitle = array(gettext("Interfaces"), gettext("Interface Assignments"));
67
$shortcut_section = "interfaces";
68

    
69
require_once("guiconfig.inc");
70
require_once("functions.inc");
71
require_once("filter.inc");
72
require_once("shaper.inc");
73
require_once("ipsec.inc");
74
require_once("vpn.inc");
75
require_once("captiveportal.inc");
76
require_once("rrd.inc");
77

    
78
function interface_assign_description($portinfo, $portname) {
79
	global $ovpn_descrs;
80
	if ($portinfo['isvlan']) {
81
		$descr = sprintf(gettext('VLAN %1$s on %2$s'), $portinfo['tag'], $portinfo['if']);
82
		$iface = convert_real_interface_to_friendly_interface_name($portinfo['if']);
83
		if (isset($iface) && strlen($iface) > 0) {
84
			$descr .= " - $iface";
85
		}
86
		if ($portinfo['descr']) {
87
			$descr .= " (" . $portinfo['descr'] . ")";
88
		}
89
	} elseif ($portinfo['iswlclone']) {
90
		$descr = $portinfo['cloneif'];
91
		if ($portinfo['descr']) {
92
			$descr .= " (" . $portinfo['descr'] . ")";
93
		}
94
	} elseif ($portinfo['isppp']) {
95
		$descr = $portinfo['descr'];
96
	} elseif ($portinfo['isbridge']) {
97
		$descr = strtoupper($portinfo['bridgeif']);
98
		if ($portinfo['descr']) {
99
			$descr .= " (" . $portinfo['descr'] . ")";
100
		}
101
	} elseif ($portinfo['isgre']) {
102
		$descr = "GRE {$portinfo['remote-addr']}";
103
		if ($portinfo['descr']) {
104
			$descr .= " (" . $portinfo['descr'] . ")";
105
		}
106
	} elseif ($portinfo['isgif']) {
107
		$descr = "GIF {$portinfo['remote-addr']}";
108
		if ($portinfo['descr']) {
109
			$descr .= " (" . $portinfo['descr'] . ")";
110
		}
111
	} elseif ($portinfo['islagg']) {
112
		$descr = strtoupper($portinfo['laggif']);
113
		if ($portinfo['descr']) {
114
			$descr .= " (" . $portinfo['descr'] . ")";
115
		}
116
	} elseif ($portinfo['isqinq']) {
117
		$descr = $portinfo['descr'];
118
	} elseif (substr($portname, 0, 4) == 'ovpn') {
119
		$descr = $portname . " (" . $ovpn_descrs[substr($portname, 5)] . ")";
120
	} else {
121
		$descr = $portname . " (" . $portinfo['mac'] . ")";
122
	}
123

    
124
	return htmlspecialchars($descr);
125
}
126

    
127
/*
128
	In this file, "port" refers to the physical port name,
129
	while "interface" refers to LAN, WAN, or OPTn.
130
*/
131

    
132
/* get list without VLAN interfaces */
133
$portlist = get_interface_list();
134

    
135
/* add wireless clone interfaces */
136
if (is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
137
	foreach ($config['wireless']['clone'] as $clone) {
138
		$portlist[$clone['cloneif']] = $clone;
139
		$portlist[$clone['cloneif']]['iswlclone'] = true;
140
	}
141
}
142

    
143
/* add VLAN interfaces */
144
if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
145
	foreach ($config['vlans']['vlan'] as $vlan) {
146
		$portlist[$vlan['vlanif']] = $vlan;
147
		$portlist[$vlan['vlanif']]['isvlan'] = true;
148
	}
149
}
150

    
151
/* add Bridge interfaces */
152
if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
153
	foreach ($config['bridges']['bridged'] as $bridge) {
154
		$portlist[$bridge['bridgeif']] = $bridge;
155
		$portlist[$bridge['bridgeif']]['isbridge'] = true;
156
	}
157
}
158

    
159
/* add GIF interfaces */
160
if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
161
	foreach ($config['gifs']['gif'] as $gif) {
162
		$portlist[$gif['gifif']] = $gif;
163
		$portlist[$gif['gifif']]['isgif'] = true;
164
	}
165
}
166

    
167
/* add GRE interfaces */
168
if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
169
	foreach ($config['gres']['gre'] as $gre) {
170
		$portlist[$gre['greif']] = $gre;
171
		$portlist[$gre['greif']]['isgre'] = true;
172
	}
173
}
174

    
175
/* add LAGG interfaces */
176
if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
177
	foreach ($config['laggs']['lagg'] as $lagg) {
178
		$portlist[$lagg['laggif']] = $lagg;
179
		$portlist[$lagg['laggif']]['islagg'] = true;
180
		/* LAGG members cannot be assigned */
181
		$lagifs = explode(',', $lagg['members']);
182
		foreach ($lagifs as $lagif) {
183
			if (isset($portlist[$lagif])) {
184
				unset($portlist[$lagif]);
185
			}
186
		}
187
	}
188
}
189

    
190
/* add QinQ interfaces */
191
if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
192
	foreach ($config['qinqs']['qinqentry'] as $qinq) {
193
		$portlist["{$qinq['vlanif']}"]['descr'] = "VLAN {$qinq['tag']} on {$qinq['if']}";
194
		$portlist["{$qinq['vlanif']}"]['isqinq'] = true;
195
		/* QinQ members */
196
		$qinqifs = explode(' ', $qinq['members']);
197
		foreach ($qinqifs as $qinqif) {
198
			$portlist["{$qinq['vlanif']}_{$qinqif}"]['descr'] = "QinQ {$qinqif} on VLAN {$qinq['tag']} on {$qinq['if']}";
199
			$portlist["{$qinq['vlanif']}_{$qinqif}"]['isqinq'] = true;
200
		}
201
	}
202
}
203

    
204
/* add PPP interfaces */
205
if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
206
	foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
207
		$portname = $ppp['if'];
208
		$portlist[$portname] = $ppp;
209
		$portlist[$portname]['isppp'] = true;
210
		$ports_base = basename($ppp['ports']);
211
		if (isset($ppp['descr'])) {
212
			$portlist[$portname]['descr'] = strtoupper($ppp['if']). "({$ports_base}) - {$ppp['descr']}";
213
		} else if (isset($ppp['username'])) {
214
			$portlist[$portname]['descr'] = strtoupper($ppp['if']). "({$ports_base}) - {$ppp['username']}";
215
		} else {
216
			$portlist[$portname]['descr'] = strtoupper($ppp['if']). "({$ports_base})";
217
		}
218
	}
219
}
220

    
221
$ovpn_descrs = array();
222
if (is_array($config['openvpn'])) {
223
	if (is_array($config['openvpn']['openvpn-server'])) {
224
		foreach ($config['openvpn']['openvpn-server'] as $s) {
225
			$portname = "ovpns{$s['vpnid']}";
226
			$portlist[$portname] = $s;
227
			$ovpn_descrs[$s['vpnid']] = $s['description'];
228
		}
229
	}
230
	if (is_array($config['openvpn']['openvpn-client'])) {
231
		foreach ($config['openvpn']['openvpn-client'] as $c) {
232
			$portname = "ovpnc{$c['vpnid']}";
233
			$portlist[$portname] = $c;
234
			$ovpn_descrs[$c['vpnid']] = $c['description'];
235
		}
236
	}
237
}
238

    
239
if (isset($_POST['add']) && isset($_POST['if_add'])) {
240
	/* Be sure this port is not being used */
241
	$portused = false;
242
	foreach ($config['interfaces'] as $ifname => $ifdata) {
243
		if ($ifdata['if'] == $_POST['if_add']) {
244
			$portused = true;
245
			break;
246
		}
247
	}
248

    
249
	if ($portused === false) {
250
		/* find next free optional interface number */
251
		if (!$config['interfaces']['lan']) {
252
			$newifname = gettext("lan");
253
			$descr = gettext("LAN");
254
		} else {
255
			for ($i = 1; $i <= count($config['interfaces']); $i++) {
256
				if (!$config['interfaces']["opt{$i}"]) {
257
					break;
258
				}
259
			}
260
			$newifname = 'opt' . $i;
261
			$descr = "OPT" . $i;
262
		}
263

    
264
		$config['interfaces'][$newifname] = array();
265
		$config['interfaces'][$newifname]['descr'] = $descr;
266
		$config['interfaces'][$newifname]['if'] = $_POST['if_add'];
267
		if (preg_match($g['wireless_regex'], $_POST['if_add'])) {
268
			$config['interfaces'][$newifname]['wireless'] = array();
269
			interface_sync_wireless_clones($config['interfaces'][$newifname], false);
270
		}
271

    
272
		uksort($config['interfaces'], "compare_interface_friendly_names");
273

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

    
277
		write_config();
278

    
279
		$savemsg = gettext("Interface has been added.");
280
		$class = "success";
281
	}
282

    
283
} else if (isset($_POST['apply'])) {
284
	if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
285
		system_reboot();
286
		$rebootingnow = true;
287
	} else {
288
		write_config();
289

    
290
		$retval = filter_configure();
291

    
292
		if (stristr($retval, "error") <> true) {
293
			$savemsg = get_std_save_message($retval);
294
			$class = "success";
295
		} else {
296
			$savemsg = $retval;
297
			$class = "danger";
298
		}
299
	}
300

    
301
} else if (isset($_POST['Submit'])) {
302

    
303
	unset($input_errors);
304

    
305
	/* input validation */
306

    
307
	/* Build a list of the port names so we can see how the interfaces map */
308
	$portifmap = array();
309
	foreach ($portlist as $portname => $portinfo) {
310
		$portifmap[$portname] = array();
311
	}
312

    
313
	/* Go through the list of ports selected by the user,
314
	build a list of port-to-interface mappings in portifmap */
315
	foreach ($_POST as $ifname => $ifport) {
316
		if (($ifname == 'lan') || ($ifname == 'wan') || (substr($ifname, 0, 3) == 'opt')) {
317
			$portifmap[$ifport][] = strtoupper($ifname);
318
		}
319
	}
320

    
321
	/* Deliver error message for any port with more than one assignment */
322
	foreach ($portifmap as $portname => $ifnames) {
323
		if (count($ifnames) > 1) {
324
			$errstr = sprintf(gettext('Port %1$s '.
325
				' was assigned to %2$s' .
326
				' interfaces:'), $portname, count($ifnames));
327

    
328
			foreach ($portifmap[$portname] as $ifn) {
329
				$errstr .= " " . convert_friendly_interface_to_friendly_descr(strtolower($ifn)) . " (" . $ifn . ")";
330
			}
331

    
332
			$input_errors[] = $errstr;
333
		} else if (count($ifnames) == 1 && preg_match('/^bridge[0-9]/', $portname) && is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
334
			foreach ($config['bridges']['bridged'] as $bridge) {
335
				if ($bridge['bridgeif'] != $portname) {
336
					continue;
337
				}
338

    
339
				$members = explode(",", strtoupper($bridge['members']));
340
				foreach ($members as $member) {
341
					if ($member == $ifnames[0]) {
342
						$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);
343
						break;
344
					}
345
				}
346
			}
347
		}
348
	}
349

    
350
	if (is_array($config['vlans']['vlan'])) {
351
		foreach ($config['vlans']['vlan'] as $vlan) {
352
			if (does_interface_exist($vlan['if']) == false) {
353
				$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']);
354
			}
355
		}
356
	}
357

    
358
	if (!$input_errors) {
359
		/* No errors detected, so update the config */
360
		foreach ($_POST as $ifname => $ifport) {
361

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

    
364
				if (!is_array($ifport)) {
365
					$reloadif = false;
366
					if (!empty($config['interfaces'][$ifname]['if']) && $config['interfaces'][$ifname]['if'] <> $ifport) {
367
						interface_bring_down($ifname);
368
						/* Mark this to be reconfigured in any case. */
369
						$reloadif = true;
370
					}
371
					$config['interfaces'][$ifname]['if'] = $ifport;
372
					if (isset($portlist[$ifport]['isppp'])) {
373
						$config['interfaces'][$ifname]['ipaddr'] = $portlist[$ifport]['type'];
374
					}
375

    
376
					if (substr($ifport, 0, 3) == 'gre' || substr($ifport, 0, 3) == 'gif') {
377
						unset($config['interfaces'][$ifname]['ipaddr']);
378
						unset($config['interfaces'][$ifname]['subnet']);
379
						unset($config['interfaces'][$ifname]['ipaddrv6']);
380
						unset($config['interfaces'][$ifname]['subnetv6']);
381
					}
382

    
383
					/* check for wireless interfaces, set or clear ['wireless'] */
384
					if (preg_match($g['wireless_regex'], $ifport)) {
385
						if (!is_array($config['interfaces'][$ifname]['wireless'])) {
386
							$config['interfaces'][$ifname]['wireless'] = array();
387
						}
388
					} else {
389
						unset($config['interfaces'][$ifname]['wireless']);
390
					}
391

    
392
					/* make sure there is a descr for all interfaces */
393
					if (!isset($config['interfaces'][$ifname]['descr'])) {
394
						$config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
395
					}
396

    
397
					if ($reloadif == true) {
398
						if (preg_match($g['wireless_regex'], $ifport)) {
399
							interface_sync_wireless_clones($config['interfaces'][$ifname], false);
400
						}
401
						/* Reload all for the interface. */
402
						interface_configure($ifname, true);
403
					}
404
				}
405
			}
406
		}
407

    
408
		write_config();
409

    
410
		enable_rrd_graphing();
411
	}
412
} else {
413
	unset($delbtn);
414
	if (!empty($_POST['del'])) {
415
		$delbtn = key($_POST['del']);
416
	}
417

    
418
	if (isset($delbtn)) {
419
		$id = $delbtn;
420

    
421
		if (link_interface_to_group($id)) {
422
			$input_errors[] = gettext("The interface is part of a group. Please remove it from the group to continue");
423
		} else if (link_interface_to_bridge($id)) {
424
			$input_errors[] = gettext("The interface is part of a bridge. Please remove it from the bridge to continue");
425
		} else if (link_interface_to_gre($id)) {
426
			$input_errors[] = gettext("The interface is part of a gre tunnel. Please delete the tunnel to continue");
427
		} else if (link_interface_to_gif($id)) {
428
			$input_errors[] = gettext("The interface is part of a gif tunnel. Please delete the tunnel to continue");
429
		} else {
430
			unset($config['interfaces'][$id]['enable']);
431
			$realid = get_real_interface($id);
432
			interface_bring_down($id);   /* down the interface */
433

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

    
436
			if (is_array($config['dhcpd']) && is_array($config['dhcpd'][$id])) {
437
				unset($config['dhcpd'][$id]);
438
				services_dhcpd_configure('inet');
439
			}
440

    
441
			if (is_array($config['dhcpdv6']) && is_array($config['dhcpdv6'][$id])) {
442
				unset($config['dhcpdv6'][$id]);
443
				services_dhcpd_configure('inet6');
444
			}
445

    
446
			if (count($config['filter']['rule']) > 0) {
447
				foreach ($config['filter']['rule'] as $x => $rule) {
448
					if ($rule['interface'] == $id) {
449
						unset($config['filter']['rule'][$x]);
450
					}
451
				}
452
			}
453
			if (is_array($config['nat']['rule']) && count($config['nat']['rule']) > 0) {
454
				foreach ($config['nat']['rule'] as $x => $rule) {
455
					if ($rule['interface'] == $id) {
456
						unset($config['nat']['rule'][$x]['interface']);
457
					}
458
				}
459
			}
460

    
461
			write_config();
462

    
463
			/* If we are in firewall/routing mode (not single interface)
464
			 * then ensure that we are not running DHCP on the wan which
465
			 * will make a lot of ISP's unhappy.
466
			 */
467
			if ($config['interfaces']['lan'] && $config['dhcpd']['wan']) {
468
				unset($config['dhcpd']['wan']);
469
			}
470

    
471
			link_interface_to_vlans($realid, "update");
472

    
473
			$savemsg = gettext("Interface has been deleted.");
474
			$class = "success";
475
		}
476
	}
477
}
478

    
479
/* Create a list of unused ports */
480
$unused_portlist = array();
481
foreach ($portlist as $portname => $portinfo) {
482
	$portused = false;
483
	foreach ($config['interfaces'] as $ifname => $ifdata) {
484
		if ($ifdata['if'] == $portname) {
485
			$portused = true;
486
			break;
487
		}
488
	}
489
	if ($portused === false) {
490
		$unused_portlist[$portname] = $portinfo;
491
	}
492
}
493

    
494
include("head.inc");
495

    
496
if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
497
	if ($_POST) {
498
		if ($rebootingnow) {
499
			$savemsg = gettext("The system is now rebooting. Please wait.");
500
			$class = "success";
501
		} else {
502
			$applymsg = gettext("Reboot is needed. Please apply the settings in order to reboot.");
503
			$class = "warning";
504
		}
505
	} else {
506
		$savemsg = gettext("Interface mismatch detected. Please resolve the mismatch, save and then click 'Apply Changes'. The firewall will reboot afterwards.");
507
		$class = "warning";
508
	}
509
}
510

    
511
if (file_exists("/tmp/reload_interfaces")) {
512
	echo "<p>\n";
513
	print_apply_box(gettext("The interface configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect."));
514
	echo "<br /></p>\n";
515
} elseif ($applymsg) {
516
	print_apply_box($applymsg);
517
} elseif ($savemsg) {
518
	print_info_box($savemsg, $class);
519
}
520

    
521
pfSense_handle_custom_code("/usr/local/pkg/interfaces_assign/pre_input_errors");
522

    
523
if ($input_errors) {
524
	print_input_errors($input_errors);
525
}
526

    
527
$tab_array = array();
528
$tab_array[] = array(gettext("Interface Assignments"), true, "interfaces_assign.php");
529
$tab_array[] = array(gettext("Interface Groups"), false, "interfaces_groups.php");
530
$tab_array[] = array(gettext("Wireless"), false, "interfaces_wireless.php");
531
$tab_array[] = array(gettext("VLANs"), false, "interfaces_vlan.php");
532
$tab_array[] = array(gettext("QinQs"), false, "interfaces_qinq.php");
533
$tab_array[] = array(gettext("PPPs"), false, "interfaces_ppps.php");
534
$tab_array[] = array(gettext("GREs"), false, "interfaces_gre.php");
535
$tab_array[] = array(gettext("GIFs"), false, "interfaces_gif.php");
536
$tab_array[] = array(gettext("Bridges"), false, "interfaces_bridge.php");
537
$tab_array[] = array(gettext("LAGGs"), false, "interfaces_lagg.php");
538
display_top_tabs($tab_array);
539
?>
540
<form action="interfaces_assign.php" method="post">
541
	<div class="table-responsive">
542
	<table class="table table-striped table-hover">
543
	<thead>
544
		<tr>
545
			<th><?=gettext("Interface")?></th>
546
			<th><?=gettext("Network port")?></th>
547
			<th>&nbsp;</th>
548
		</tr>
549
	</thead>
550
	<tbody>
551
<?php
552
	foreach ($config['interfaces'] as $ifname => $iface):
553
		if ($iface['descr']) {
554
			$ifdescr = $iface['descr'];
555
		} else {
556
			$ifdescr = strtoupper($ifname);
557
		}
558
?>
559
		<tr>
560
			<td><a href="/interfaces.php?if=<?=$ifname?>"><?=$ifdescr?></a></td>
561
			<td>
562
				<select name="<?=$ifname?>" id="<?=$ifname?>" class="form-control">
563
<?php foreach ($portlist as $portname => $portinfo):?>
564
					<option value="<?=$portname?>" <?=($portname == $iface['if']) ? ' selected': ''?>>
565
						<?=interface_assign_description($portinfo, $portname)?>
566
					</option>
567
<?php endforeach;?>
568
				</select>
569
			</td>
570
			<td>
571
<?php if ($ifname != 'wan'):?>
572
				<button type="submit" name="del[<?=$ifname?>]" class="btn btn-danger btn-sm" title="<?=gettext("Delete interface")?>">
573
					<i class="fa fa-trash icon-embed-btn"></i>
574
					<?=gettext("Delete")?>
575
				</button>
576
<?php endif;?>
577
			</td>
578
		</tr>
579
<?php endforeach;
580
	if (count($config['interfaces']) < count($portlist)):
581
?>
582
		<tr>
583
			<th>
584
				<?=gettext("Available network ports:")?>
585
			</th>
586
			<td>
587
				<select name="if_add" id="if_add" class="form-control">
588
<?php foreach ($unused_portlist as $portname => $portinfo):?>
589
					<option value="<?=$portname?>" <?=($portname == $iface['if']) ? ' selected': ''?>>
590
						<?=interface_assign_description($portinfo, $portname)?>
591
					</option>
592
<?php endforeach;?>
593
				</select>
594
			</td>
595
			<td>
596
				<button type="submit" name="add" title="<?=gettext("Add selected interface")?>" value="add interface" class="btn btn-success btn-sm" >
597
					<i class="fa fa-plus icon-embed-btn"></i>
598
					<?=gettext("Add")?>
599
				</button>
600
			</td>
601
		</tr>
602
<?php endif;?>
603
		</tbody>
604
	</table>
605
	</div>
606

    
607
	<button name="Submit" type="submit" class="btn btn-primary" value="<?=gettext('Save')?>"><i class="fa fa-save icon-embed-btn"></i><?=gettext('Save')?></button>
608
</form>
609
<br />
610

    
611
<?php
612
print_info_box(gettext("Interfaces that are configured as members of a lagg(4) interface will not be shown."), 'info', false);
613
?>
614

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