Project

General

Profile

Download (19.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-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2022 Rubicon Communications, LLC (Netgate)
9
 * All rights reserved.
10
 *
11
 * originally based on m0n0wall (http://m0n0.ch/wall)
12
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
13
 * Written by Jim McBeath based on existing m0n0wall files
14
 * All rights reserved.
15
 *
16
 * Licensed under the Apache License, Version 2.0 (the "License");
17
 * you may not use this file except in compliance with the License.
18
 * You may obtain a copy of the License at
19
 *
20
 * http://www.apache.org/licenses/LICENSE-2.0
21
 *
22
 * Unless required by applicable law or agreed to in writing, software
23
 * distributed under the License is distributed on an "AS IS" BASIS,
24
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
 * See the License for the specific language governing permissions and
26
 * limitations under the License.
27
 */
28

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

    
36
//$timealla = microtime(true);
37

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

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

    
51
global $friendlyifnames;
52

    
53
global $config;
54

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

    
58
/*
59
	In this file, "port" refers to the physical port name,
60
	while "interface" refers to LAN, WAN, or OPTn.
61
*/
62

    
63
/* get list without VLAN interfaces */
64
$portlist = get_interface_list();
65

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

    
71
/* add wireless clone interfaces */
72
if (isset($config['wireless']['clone']) && is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
73
	foreach ($config['wireless']['clone'] as $clone) {
74
		$portlist[$clone['cloneif']] = $clone;
75
		$portlist[$clone['cloneif']]['iswlclone'] = true;
76
	}
77
}
78

    
79
/* add VLAN interfaces */
80
if (isset($config['vlans']['vlan']) && is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
81
	//$timea = microtime(true);
82
	foreach ($config['vlans']['vlan'] as $vlan) {
83
		$portlist[$vlan['vlanif']] = $vlan;
84
		$portlist[$vlan['vlanif']]['isvlan'] = true;
85
	}
86
}
87

    
88
/* add Bridge interfaces */
89
if (isset($config['bridges']['bridged']) && is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
90
	foreach ($config['bridges']['bridged'] as $bridge) {
91
		$portlist[$bridge['bridgeif']] = $bridge;
92
		$portlist[$bridge['bridgeif']]['isbridge'] = true;
93
	}
94
}
95

    
96
/* add GIF interfaces */
97
if (isset($config['gifs']['gif']) && is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
98
	foreach ($config['gifs']['gif'] as $gif) {
99
		$portlist[$gif['gifif']] = $gif;
100
		$portlist[$gif['gifif']]['isgif'] = true;
101
	}
102
}
103

    
104
/* add GRE interfaces */
105
if (isset($config['gres']['gre']) && is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
106
	foreach ($config['gres']['gre'] as $gre) {
107
		$portlist[$gre['greif']] = $gre;
108
		$portlist[$gre['greif']]['isgre'] = true;
109
	}
110
}
111

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

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

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

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

    
176
global $ipsec_descrs;
177
$ipsec_descrs = interface_ipsec_vti_list_all();
178
foreach ($ipsec_descrs as $ifname => $ifdescr) {
179
	$portlist[$ifname] = array('descr' => $ifdescr);
180
}
181

    
182

    
183
$ifdescrs = interface_assign_description_fast($portlist,$friendlyifnames);
184

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

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

    
210
		$config['interfaces'][$newifname] = array();
211
		$config['interfaces'][$newifname]['descr'] = $descr;
212
		$config['interfaces'][$newifname]['if'] = $_POST['if_add'];
213
		if (preg_match($g['wireless_regex'], $_POST['if_add'])) {
214
			$config['interfaces'][$newifname]['wireless'] = array();
215
			interface_sync_wireless_clones($config['interfaces'][$newifname], false);
216
		}
217

    
218

    
219
		uksort($config['interfaces'], "compare_interface_friendly_names");
220

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

    
224
		write_config("New interface assigned");
225

    
226
		filter_configure();
227

    
228
		$action_msg = gettext("Interface has been added.");
229
		$class = "success";
230
	}
231

    
232
} else if (isset($_POST['apply'])) {
233
	if (file_exists("/var/run/interface_mismatch_reboot_needed")) {
234
		system_reboot();
235
		$rebootingnow = true;
236
	} else {
237
		write_config("Interfaces assignment settings changed");
238

    
239
		$changes_applied = true;
240
		$retval = 0;
241
		$retval |= filter_configure();
242
	}
243

    
244
} else if (isset($_POST['Submit'])) {
245

    
246
	unset($input_errors);
247

    
248
	/* input validation */
249

    
250
	/* Build a list of the port names so we can see how the interfaces map */
251
	$portifmap = array();
252
	foreach ($portlist as $portname => $portinfo) {
253
		$portifmap[$portname] = array();
254
	}
255

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

    
268
	/* Deliver error message for any port with more than one assignment */
269
	foreach ($portifmap as $portname => $ifnames) {
270
		if (count($ifnames) > 1) {
271
			$errstr = sprintf(gettext('Port %1$s '.
272
				' was assigned to %2$s' .
273
				' interfaces:'), $portname, count($ifnames));
274

    
275
			foreach ($portifmap[$portname] as $ifn) {
276
				$errstr .= " " . convert_friendly_interface_to_friendly_descr(strtolower($ifn)) . " (" . $ifn . ")";
277
			}
278

    
279
			$input_errors[] = $errstr;
280
		} else if (count($ifnames) == 1 && preg_match('/^bridge[0-9]/', $portname) && is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
281
			foreach ($config['bridges']['bridged'] as $bridge) {
282
				if ($bridge['bridgeif'] != $portname) {
283
					continue;
284
				}
285

    
286
				$members = explode(",", strtoupper($bridge['members']));
287
				foreach ($members as $member) {
288
					if ($member == $ifnames[0]) {
289
						$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);
290
						break;
291
					}
292
				}
293
			}
294
		}
295
	}
296

    
297
	foreach (config_get_path('vlans/vlan', []) as $vlan) {
298
		if (does_interface_exist($vlan['if']) == false) {
299
			$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']);
300
		}
301
	}
302

    
303
	if (!$input_errors) {
304
		/* No errors detected, so update the config */
305
		$filter_reload = false;
306
		foreach ($_POST as $ifname => $ifport) {
307

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

    
310
				if (!is_array($ifport)) {
311
					$reloadif = false;
312
					if (!empty($config['interfaces'][$ifname]['if']) && $config['interfaces'][$ifname]['if'] <> $ifport) {
313
						interface_bring_down($ifname);
314
						/* Mark this to be reconfigured in any case. */
315
						$reloadif = true;
316
						$filter_reload = true;
317
						$gateway_monitor_reload = true;
318
					}
319
					$config['interfaces'][$ifname]['if'] = $ifport;
320
					if (isset($portlist[$ifport]['isppp'])) {
321
						$config['interfaces'][$ifname]['ipaddr'] = $portlist[$ifport]['type'];
322
					}
323

    
324
					if ((substr($ifport, 0, 3) == 'gre') ||
325
					    (substr($ifport, 0, 5) == 'gif')) {
326
						unset($config['interfaces'][$ifname]['ipaddr']);
327
						unset($config['interfaces'][$ifname]['subnet']);
328
						unset($config['interfaces'][$ifname]['ipaddrv6']);
329
						unset($config['interfaces'][$ifname]['subnetv6']);
330
					}
331

    
332
					/* check for wireless interfaces, set or clear ['wireless'] */
333
					if (preg_match($g['wireless_regex'], $ifport)) {
334
						if (!is_array($config['interfaces'][$ifname]['wireless'])) {
335
							$config['interfaces'][$ifname]['wireless'] = array();
336
						}
337
					} else {
338
						unset($config['interfaces'][$ifname]['wireless']);
339
					}
340

    
341
					/* make sure there is a descr for all interfaces */
342
					if (!isset($config['interfaces'][$ifname]['descr'])) {
343
						$config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
344
					}
345

    
346
					if ($reloadif == true) {
347
						if (preg_match($g['wireless_regex'], $ifport)) {
348
							interface_sync_wireless_clones($config['interfaces'][$ifname], false);
349
						}
350
						/* Reload all for the interface. */
351
						interface_configure($ifname, true);
352
						$filter_reload = true;
353
					}
354
				}
355
			}
356
		}
357
		/* regenerated ruleset after re-assigning the interface,
358
		 * see https://redmine.pfsense.org/issues/12949 */
359
		if ($filter_reload) {
360
			filter_configure();
361
		}
362
		if ($gateway_monitor_reload) {
363
			setup_gateways_monitor();
364
		}
365
		write_config("Interfaces assignment settings changed");
366

    
367
		enable_rrd_graphing();
368
	}
369
} else {
370
	unset($delbtn);
371
	if (!empty($_POST['del'])) {
372
		$delbtn = key($_POST['del']);
373
	}
374

    
375
	if (isset($delbtn)) {
376
		$id = $delbtn;
377

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

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

    
395
			init_config_arr(['dhcpd', $id]);
396

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

    
402
			init_config_arr(['dhcpdv6', $id]);
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
			init_config_arr(['filter', 'rule']);
410

    
411
			foreach ($config['filter']['rule'] as $x => $rule) {
412
				if ($rule['interface'] == $id) {
413
					unset($config['filter']['rule'][$x]);
414
				}
415
			}
416

    
417
			init_config_arr(['nat', 'rule']);
418
		
419
			foreach ($config['nat']['rule'] as $x => $rule) {
420
				if ($rule['interface'] == $id) {
421
					unset($config['nat']['rule'][$x]['interface']);
422
				}
423
			}
424

    
425
			write_config(gettext('Interface assignment deleted'));
426

    
427
			/* If we are in firewall/routing mode (not single interface)
428
			 * then ensure that we are not running DHCP on the wan which
429
			 * will make a lot of ISPs unhappy.
430
			 */
431
			if (config_path_enabled('interfaces', 'lan')
432
				&& config_path_enabled('dhcpd', 'wan')) {
433
					config_del_path('dhcp/wan');
434
			}
435

    
436
			link_interface_to_vlans($realid, "update");
437

    
438
			filter_configure();
439

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

    
446
/* Create a list of unused ports */
447
$unused_portlist = array();
448
$portArray = array_keys($portlist);
449

    
450
$ifaceArray = array_column($config['interfaces'],'if');
451
$unused = array_diff($portArray,$ifaceArray);
452
$unused = array_flip($unused);
453
$unused_portlist = array_intersect_key($portlist,$unused);//*/
454
unset($unused,$portArray,$ifaceArray);
455

    
456
include("head.inc");
457

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

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

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

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

    
491
$tab_array = array();
492
$tab_array[] = array(gettext("Interface Assignments"), true, "interfaces_assign.php");
493
$tab_array[] = array(gettext("Interface Groups"), false, "interfaces_groups.php");
494
$tab_array[] = array(gettext("Wireless"), false, "interfaces_wireless.php");
495
$tab_array[] = array(gettext("VLANs"), false, "interfaces_vlan.php");
496
$tab_array[] = array(gettext("QinQs"), false, "interfaces_qinq.php");
497
$tab_array[] = array(gettext("PPPs"), false, "interfaces_ppps.php");
498
$tab_array[] = array(gettext("GREs"), false, "interfaces_gre.php");
499
$tab_array[] = array(gettext("GIFs"), false, "interfaces_gif.php");
500
$tab_array[] = array(gettext("Bridges"), false, "interfaces_bridge.php");
501
$tab_array[] = array(gettext("LAGGs"), false, "interfaces_lagg.php");
502
display_top_tabs($tab_array);
503

    
504
/*Generate the port select box only once.
505
Not indenting the HTML to produce smaller code
506
and faster page load times */
507

    
508
$portselect='';
509
foreach ($portlist as $portname => $portinfo) {
510
	$portselect.='<option value="'.$portname.'"';
511
	$portselect.=">".$ifdescrs[$portname]."</option>\n";
512
}
513

    
514
?>
515
<form action="interfaces_assign.php" method="post">
516
	<div class="table-responsive">
517
	<table class="table table-striped table-hover">
518
	<thead>
519
		<tr>
520
			<th><?=gettext("Interface")?></th>
521
			<th><?=gettext("Network port")?></th>
522
			<th>&nbsp;</th>
523
		</tr>
524
	</thead>
525
	<tbody>
526
<?php
527
	$i=0;
528
	foreach ($config['interfaces'] as $ifname => $iface):
529
		if ($iface['descr']) {
530
			$ifdescr = $iface['descr'];
531
		} else {
532
			$ifdescr = strtoupper($ifname);
533
		}
534
?>
535
		<tr>
536
			<td><a href="/interfaces.php?if=<?=$ifname?>"><?=$ifdescr?></a></td>
537
			<td>
538
				<select name="<?=$ifname?>" id="<?=$ifname?>" class="form-control">
539
<?php
540
/*port select menu generation loop replaced with pre-prepared select menu to reduce page generation time */
541
echo str_replace('value="'.$iface['if'].'">','value="'.$iface['if'].'" selected>',$portselect);
542
?>
543
				</select>
544
			</td>
545
			<td>
546
<?php if ($ifname != 'wan'):?>
547
				<button type="submit" name="del[<?=$ifname?>]" class="btn btn-danger btn-sm" title="<?=$gettextArray['deleteif']?>">
548
					<i class="fa fa-trash icon-embed-btn"></i>
549
					<?=$gettextArray["delete"]?>
550
				</button>
551
<?php endif;?>
552
			</td>
553
		</tr>
554
<?php $i++;
555
endforeach;
556
	if (count($config['interfaces']) < count($portlist)):
557
?>
558
		<tr>
559
			<th>
560
				<?=gettext("Available network ports:")?>
561
			</th>
562
			<td>
563
				<select name="if_add" id="if_add" class="form-control">
564
<?php
565
/* HTML not indented to save on transmission/render time */
566
foreach ($unused_portlist as $portname => $portinfo):?>
567
<option value="<?=$portname?>" <?=($portname == $iface['if']) ? ' selected': ''?>><?=$ifdescrs[$portname]?></option>
568
<?php endforeach;
569
?>
570
				</select>
571
			</td>
572
			<td>
573
				<button type="submit" name="add" title="<?=gettext("Add selected interface")?>" value="add interface" class="btn btn-success btn-sm" >
574
					<i class="fa fa-plus icon-embed-btn"></i>
575
					<?=$gettextArray["add"]?>
576
				</button>
577
			</td>
578
		</tr>
579
<?php endif;?>
580
		</tbody>
581
	</table>
582
	</div>
583

    
584
	<button name="Submit" type="submit" class="btn btn-primary" value="<?=gettext('Save')?>"><i class="fa fa-save icon-embed-btn"></i><?=gettext('Save')?></button>
585
</form>
586
<br />
587

    
588
<?php
589
print_info_box(gettext("Interfaces that are configured as members of a lagg(4) interface will not be shown.") .
590
    '<br/><br/>' .
591
    gettext("Wireless interfaces must be created on the Wireless tab before they can be assigned."), 'info', false);
592
?>
593

    
594
<?php include("foot.inc")?>
(72-72/228)