Project

General

Profile

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

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

    
67
$pgtitle = array(gettext("Interfaces"), gettext("Assign network ports"));
68
$shortcut_section = "interfaces";
69

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

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

    
121
	return htmlspecialchars($descr);
122
}
123

    
124
/*
125
	In this file, "port" refers to the physical port name,
126
	while "interface" refers to LAN, WAN, or OPTn.
127
*/
128

    
129
/* get list without VLAN interfaces */
130
$portlist = get_interface_list();
131

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

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

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

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

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

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

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

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

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

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

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

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

    
269
		uksort($config['interfaces'], "compare_interface_friendly_names");
270

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

    
274
		write_config();
275

    
276
		$savemsg = gettext("Interface has been added.");
277
	}
278

    
279
} else if (isset($_POST['apply'])) {
280
	if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
281
		system_reboot();
282
		$rebootingnow = true;
283
	} else {
284
		write_config();
285

    
286
		$retval = filter_configure();
287
		$savemsg = get_std_save_message($retval);
288

    
289
		if (stristr($retval, "error") <> true) {
290
			$savemsg = get_std_save_message($retval);
291
		} else {
292
			$savemsg = $retval;
293
		}
294
	}
295

    
296
} else if (isset($_POST['Submit'])) {
297

    
298
	unset($input_errors);
299

    
300
	/* input validation */
301

    
302
	/* Build a list of the port names so we can see how the interfaces map */
303
	$portifmap = array();
304
	foreach ($portlist as $portname => $portinfo) {
305
		$portifmap[$portname] = array();
306
	}
307

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

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

    
323
			foreach ($portifmap[$portname] as $ifn) {
324
				$errstr .= " " . convert_friendly_interface_to_friendly_descr(strtolower($ifn)) . " (" . $ifn . ")";
325
			}
326

    
327
			$input_errors[] = $errstr;
328
		} else if (count($ifnames) == 1 && preg_match('/^bridge[0-9]/', $portname) && is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
329
			foreach ($config['bridges']['bridged'] as $bridge) {
330
				if ($bridge['bridgeif'] != $portname) {
331
					continue;
332
				}
333

    
334
				$members = explode(",", strtoupper($bridge['members']));
335
				foreach ($members as $member) {
336
					if ($member == $ifnames[0]) {
337
						$input_errors[] = sprintf(gettext("You cannot set port %s to interface %s because this interface is a member of %s."), $portname, $member, $portname);
338
						break;
339
					}
340
				}
341
			}
342
		}
343
	}
344

    
345
	if (is_array($config['vlans']['vlan'])) {
346
		foreach ($config['vlans']['vlan'] as $vlan) {
347
			if (does_interface_exist($vlan['if']) == false) {
348
				$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.";
349
			}
350
		}
351
	}
352

    
353
	if (!$input_errors) {
354
		/* No errors detected, so update the config */
355
		foreach ($_POST as $ifname => $ifport) {
356

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

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

    
371
					if (substr($ifport, 0, 3) == 'gre' || substr($ifport, 0, 3) == 'gif') {
372
						unset($config['interfaces'][$ifname]['ipaddr']);
373
						unset($config['interfaces'][$ifname]['subnet']);
374
						unset($config['interfaces'][$ifname]['ipaddrv6']);
375
						unset($config['interfaces'][$ifname]['subnetv6']);
376
					}
377

    
378
					/* check for wireless interfaces, set or clear ['wireless'] */
379
					if (preg_match($g['wireless_regex'], $ifport)) {
380
						if (!is_array($config['interfaces'][$ifname]['wireless'])) {
381
							$config['interfaces'][$ifname]['wireless'] = array();
382
						}
383
					} else {
384
						unset($config['interfaces'][$ifname]['wireless']);
385
					}
386

    
387
					/* make sure there is a descr for all interfaces */
388
					if (!isset($config['interfaces'][$ifname]['descr'])) {
389
						$config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
390
					}
391

    
392
					if ($reloadif == true) {
393
						if (preg_match($g['wireless_regex'], $ifport)) {
394
							interface_sync_wireless_clones($config['interfaces'][$ifname], false);
395
						}
396
						/* Reload all for the interface. */
397
						interface_configure($ifname, true);
398
					}
399
				}
400
			}
401
		}
402

    
403
		write_config();
404

    
405
		enable_rrd_graphing();
406
	}
407
} else {
408
	unset($delbtn);
409
	if (!empty($_POST['del'])) {
410
		$delbtn = key($_POST['del']);
411
	}
412

    
413
	if (isset($delbtn)) {
414
		$id = $delbtn;
415

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

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

    
431
			if (is_array($config['dhcpd']) && is_array($config['dhcpd'][$id])) {
432
				unset($config['dhcpd'][$id]);
433
				services_dhcpd_configure();
434
			}
435

    
436
			if (count($config['filter']['rule']) > 0) {
437
				foreach ($config['filter']['rule'] as $x => $rule) {
438
					if ($rule['interface'] == $id) {
439
						unset($config['filter']['rule'][$x]);
440
					}
441
				}
442
			}
443
			if (is_array($config['nat']['rule']) && count($config['nat']['rule']) > 0) {
444
				foreach ($config['nat']['rule'] as $x => $rule) {
445
					if ($rule['interface'] == $id) {
446
						unset($config['nat']['rule'][$x]['interface']);
447
					}
448
				}
449
			}
450

    
451
			write_config();
452

    
453
			/* If we are in firewall/routing mode (not single interface)
454
			 * then ensure that we are not running DHCP on the wan which
455
			 * will make a lot of ISP's unhappy.
456
			 */
457
			if ($config['interfaces']['lan'] && $config['dhcpd']['wan']) {
458
				unset($config['dhcpd']['wan']);
459
			}
460

    
461
			link_interface_to_vlans($realid, "update");
462

    
463
			$savemsg = gettext("Interface has been deleted.");
464
		}
465
	}
466
}
467

    
468
/* Create a list of unused ports */
469
$unused_portlist = array();
470
foreach ($portlist as $portname => $portinfo) {
471
	$portused = false;
472
	foreach ($config['interfaces'] as $ifname => $ifdata) {
473
		if ($ifdata['if'] == $portname) {
474
			$portused = true;
475
			break;
476
		}
477
	}
478
	if ($portused === false) {
479
		$unused_portlist[$portname] = $portinfo;
480
	}
481
}
482

    
483
include("head.inc");
484

    
485
if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
486
	if ($_POST) {
487
		if ($rebootingnow) {
488
			$savemsg = gettext("The system is now rebooting.  Please wait.");
489
		} else {
490
			$savemsg = gettext("Reboot is needed. Please apply the settings in order to reboot.");
491
		}
492
	} else {
493
		$savemsg = gettext("Interface mismatch detected.  Please resolve the mismatch and click 'Apply changes'.  The firewall will reboot afterwards.");
494
	}
495
}
496

    
497
if (file_exists("/tmp/reload_interfaces")) {
498
	echo "<p>\n";
499
	print_info_box_np(gettext("The interface configuration has been changed.<br />You must apply the changes in order for them to take effect."));
500
	echo "<br /></p>\n";
501
} elseif ($savemsg) {
502
	print_info_box($savemsg);
503
}
504

    
505
pfSense_handle_custom_code("/usr/local/pkg/interfaces_assign/pre_input_errors");
506

    
507
if ($input_errors) {
508
	print_input_errors($input_errors);
509
}
510

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

    
590
	<button name="Submit" type="submit" class="btn btn-primary" value="<?=gettext('Save')?>"><?=gettext('Save')?></button>
591
</form>
592
<br />
593
<p class="alert alert-info"><?=gettext("Interfaces that are configured as members of a lagg(4) interface will not be shown.")?></p>
594

    
595
<?php include("foot.inc")?>
(70-70/228)