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
	if (is_array($config['vlans']['vlan'])) {
298
		foreach ($config['vlans']['vlan'] as $vlan) {
299
			if (does_interface_exist($vlan['if']) == false) {
300
				$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']);
301
			}
302
		}
303
	}
304

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

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

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

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

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

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

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

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

    
373
	if (isset($delbtn)) {
374
		$id = $delbtn;
375

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

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

    
393
			init_config_arr(['dhcpd', $id]);
394

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

    
400
			init_config_arr(['dhcpdv6', $id]);
401

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

    
407
			init_config_arr(['filter', 'rule']);
408

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

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

    
423
			write_config(gettext('Interface assignment deleted'));
424

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

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

    
435
			filter_configure();
436

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

    
443
/* Create a list of unused ports */
444
$unused_portlist = array();
445
$portArray = array_keys($portlist);
446

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

    
453
include("head.inc");
454

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

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

    
482
pfSense_handle_custom_code("/usr/local/pkg/interfaces_assign/pre_input_errors");
483

    
484
if ($input_errors) {
485
	print_input_errors($input_errors);
486
}
487

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

    
501
/*Generate the port select box only once.
502
Not indenting the HTML to produce smaller code
503
and faster page load times */
504

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

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

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

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

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