Project

General

Profile

Download (143 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2
/*
3
	interfaces.inc
4 eba938e3 Scott Ullrich
	Copyright (C) 2004-2008 Scott Ullrich
5 a687f866 Namezero
	Copyright (C) 2008-2009 Ermal Lu?i
6 ac3f8318 Espen Johansen
	All rights reserved.
7
8
	function interfaces_wireless_configure is
9
	Copyright (C) 2005 Espen Johansen
10 cfc707f7 Scott Ullrich
	All rights reserved.
11
12
	originally part of m0n0wall (http://m0n0.ch/wall)
13 5b237745 Scott Ullrich
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
	All rights reserved.
15 cfc707f7 Scott Ullrich
16 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
17
	modification, are permitted provided that the following conditions are met:
18 cfc707f7 Scott Ullrich
19 ac3f8318 Espen Johansen
	1. Redistributions of source code must retain the above copyright notices,
20 5b237745 Scott Ullrich
	   this list of conditions and the following disclaimer.
21 cfc707f7 Scott Ullrich
22 5b237745 Scott Ullrich
	2. Redistributions in binary form must reproduce the above copyright
23 ac3f8318 Espen Johansen
	   notices, this list of conditions and the following disclaimer in the
24 5b237745 Scott Ullrich
	   documentation and/or other materials provided with the distribution.
25 cfc707f7 Scott Ullrich
26 5b237745 Scott Ullrich
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
27
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
	POSSIBILITY OF SUCH DAMAGE.
36 523855b0 Scott Ullrich
37 b0c6a4f1 Ermal
	pfSense_BUILDER_BINARIES:	/sbin/dhclient	/bin/sh	/usr/bin/grep	/usr/bin/xargs	/usr/bin/awk	/usr/local/sbin/choparp
38 89c52814 Ermal
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/sbin/route	/usr/sbin/ngctl	/usr/sbin/arp	/bin/kill	/usr/local/sbin/mpd5
39 d53a9a51 smos
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/dhcp6c
40 523855b0 Scott Ullrich
	pfSense_MODULE:	interfaces
41
42 5b237745 Scott Ullrich
*/
43
44
/* include all configuration functions */
45 7387844e Chris Buechler
require_once("globals.inc");
46 9a456170 Darren Embry
require_once("util.inc");
47 36b2d82d smos
require_once("gwlb.inc");
48 5b237745 Scott Ullrich
49 b5b957fe Scott Ullrich
function interfaces_bring_up($interface) {
50
	if(!$interface) {
51 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("interfaces_bring_up() was called but no variable defined."));
52 ec054b7c Scott Ullrich
		log_error( "Backtrace: " . debug_backtrace() );
53 b5b957fe Scott Ullrich
		return;
54
	}
55 871768cf Ermal
	pfSense_interface_flags($interface, IFF_UP);
56 b5b957fe Scott Ullrich
}
57
58 52947718 Ermal Lu?i
/*
59
 * Return the interface array
60
 */
61
function get_interface_arr($flush = false) {
62 1c3ddd9e Renato Botelho
	global $interface_arr_cache;
63 52947718 Ermal Lu?i
64 1c3ddd9e Renato Botelho
	/* If the cache doesn't exist, build it */
65
	if (!isset($interface_arr_cache) or $flush)
66
		$interface_arr_cache = pfSense_interface_listget();
67 52947718 Ermal Lu?i
68 1c3ddd9e Renato Botelho
	return $interface_arr_cache;
69 52947718 Ermal Lu?i
}
70
71
/*
72
 * does_interface_exist($interface): return true or false if a interface is
73
 * detected.
74
 */
75
function does_interface_exist($interface) {
76 8256f324 gnhb
	global $config;
77 be45aa79 Renato Botelho
78 8256f324 gnhb
	if(!$interface)
79 72993196 Ermal
		return false;
80 52947718 Ermal Lu?i
81 72993196 Ermal
	$ints = get_interface_arr(true);
82 6d5446a2 Ermal
	if (in_array($interface, $ints))
83 8256f324 gnhb
		return true;
84
	else
85
		return false;
86 52947718 Ermal Lu?i
}
87
88 2708a5cf Ermal
/*
89
 * does_vip_exist($vip): return true or false if a vip is
90
 * configured.
91
 */
92
function does_vip_exist($vip) {
93
	global $config;
94 be45aa79 Renato Botelho
95 2708a5cf Ermal
	if(!$vip)
96
		return false;
97
98
99 b526daaf Ermal
	switch ($vip['mode']) {
100 2708a5cf Ermal
	case "carp":
101 7b47bd4c Ermal
		$realif = "{$vip['interface']}_vip{$vip['vhid']}";
102 b526daaf Ermal
		if (!does_interface_exist($realif)) {
103
			return false;
104
		}
105
		break;
106 2708a5cf Ermal
	case "ipalias":
107 b526daaf Ermal
		$realif = get_real_interface($vip['interface']);
108
		if (!does_interface_exist($realif)) {
109
			return false;
110 2708a5cf Ermal
		}
111
		break;
112
	case "proxyarp":
113
		/* XXX: Implement this */
114 b526daaf Ermal
	default:
115
		return false;
116
	}
117
118
	$ifacedata = pfSense_getall_interface_addresses($realif);
119
	foreach ($ifacedata as $vipips) {
120
		if ($vipips == "{$vip['subnet']}/{$vip['subnet_bits']}")
121
			return true;
122 2708a5cf Ermal
	}
123
124
	return false;
125
}
126
127 67b057a9 Ermal
function interface_netgraph_needed($interface = "wan") {
128
	global $config;
129
130
	$found = false;
131
	if (!empty($config['pptpd']) &&
132
		$config['pptpd']['mode'] == "server")
133
		$found = true;
134
	if ($found == false && !empty($config['l2tp']) &&
135
		$config['l2tp']['mode'] == "server")
136
		$found = true;
137
	if ($found == false && is_array($config['pppoes']['pppoe'])) {
138
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
139
			if ($pppoe['mode'] != "server")
140
				continue;
141
			if ($pppoe['interface'] == $interface)
142
				$found = true;
143
				break;
144
		}
145
	}
146 3dfc2d1a Ermal
	if ($found == false) {
147
		if (!empty($config['interfaces'][$interface])) {
148
			switch ($config['interfaces'][$interface]['ipaddr']) {
149
			case "ppp":
150
			case "pppoe":
151
			case "l2tp":
152
			case "pptp":
153
				$found = true;
154
				break;
155
			default:
156
				$found = false;
157
				break;
158
			}
159 9d7d2388 Ermal
		}
160
	}
161
	if ($found == false) {
162
		$realif = get_real_interface($interface);
163
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
164
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
165 20cb9803 gnhb
166
/* This if block doesn't do anything. It can be deleted.
167
PPP interfaces are found above in the previous if ($found == false) block.
168
This block of code is only entered for OPTx interfaces that are configured for PPPoE modem access, so $realif != $ppp['if']
169
170 9d7d2388 Ermal
				if ($realif == $ppp['if']) {
171
					$found = true;
172
					break;
173 3dfc2d1a Ermal
				}
174 be45aa79 Renato Botelho
*/
175 3eb00b49 gnhb
				$ports = explode(',',$ppp['ports']);
176
				foreach($ports as $pid => $port){
177 20cb9803 gnhb
					$port = get_real_interface($port);
178 3eb00b49 gnhb
					if ($realif == $port) {
179
						$found = true;
180
						break;
181
					}
182 be45aa79 Renato Botelho
					/* Find the parent interfaces of the vlans in the MLPPP configs
183
					* there should be only one element in the array here
184 20cb9803 gnhb
					* -- this could be better . . . */
185
					$parent_if = get_parent_interface($port);
186
					if ($realif == $parent_if[0]) {
187
						$found = true;
188
						break;
189
					}
190 3eb00b49 gnhb
				}
191 9d7d2388 Ermal
			}
192 67b057a9 Ermal
		}
193
	}
194 be45aa79 Renato Botelho
195 31eee4a6 Ermal
	if ($found == false) {
196
		$realif = get_real_interface($interface);
197 67b057a9 Ermal
		pfSense_ngctl_detach("{$realif}:", $realif);
198 31eee4a6 Ermal
	}
199 92a1c8e6 Ermal
	/* NOTE: We make sure for this on interface_ppps_configure()
200
	 *	no need to do it here agan.
201
	 *	else
202
	 *		pfSense_ngctl_attach(".", $realif);
203
	 */
204 67b057a9 Ermal
}
205
206 eba938e3 Scott Ullrich
function interfaces_loopback_configure() {
207 7734aea6 Andrew Thompson
	global $g;
208
209
	if ($g['platform'] == 'jail')
210
		return;
211 7a6f7c55 Scott Ullrich
	if($g['booting'])
212 07e40c1f Carlos Eduardo Ramos
		echo gettext("Configuring loopback interface...");
213 871768cf Ermal
	pfSense_interface_setaddress("lo0", "127.0.0.1");
214 b5b957fe Scott Ullrich
	interfaces_bring_up("lo0");
215 7a6f7c55 Scott Ullrich
	if($g['booting'])
216 07e40c1f Carlos Eduardo Ramos
		echo gettext("done.") . "\n";
217 5b237745 Scott Ullrich
	return 0;
218
}
219
220 eba938e3 Scott Ullrich
function interfaces_vlan_configure() {
221 7a6f7c55 Scott Ullrich
	global $config, $g;
222 87519eb7 Scott Ullrich
	if($g['booting'])
223 07e40c1f Carlos Eduardo Ramos
		echo gettext("Configuring VLAN interfaces...");
224 5b6eac01 Scott Ullrich
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
225 e1c449c0 Ermal Lu?i
		foreach ($config['vlans']['vlan'] as $vlan) {
226 f620d00d Ermal Luçi
			if(empty($vlan['vlanif']))
227 48315e65 Ermal Luci
				$vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}";
228 5b6eac01 Scott Ullrich
			/* XXX: Maybe we should report any errors?! */
229 5f1e1d26 Ermal Lu?i
			interface_vlan_configure($vlan);
230 517feb1c Seth Mos
		}
231 5b6eac01 Scott Ullrich
	}
232 87519eb7 Scott Ullrich
	if($g['booting'])
233 07e40c1f Carlos Eduardo Ramos
		echo gettext("done.") . "\n";
234 2075fadb Ermal Luçi
}
235 cfc707f7 Scott Ullrich
236 abcb2bed Ermal Lu?i
function interface_vlan_configure(&$vlan) {
237 1c3ddd9e Renato Botelho
	global $config, $g;
238 161040eb Scott Ullrich
239 5f1e1d26 Ermal Lu?i
	if (!is_array($vlan)) {
240 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("VLAN: called with wrong options. Problems with config!"));
241 5f1e1d26 Ermal Lu?i
		return;
242
	}
243
	$if = $vlan['if'];
244 48315e65 Ermal Luci
	$vlanif  = empty($vlan['vlanif']) ? "{$if}_vlan{$vlan['tag']}" : $vlan['vlanif'];
245 5f1e1d26 Ermal Lu?i
	$tag = $vlan['tag'];
246
247 871768cf Ermal
	if (empty($if)) {
248 905ea336 Phil Davis
		log_error(gettext("interface_vlan_configure called with if undefined."));
249 3ae4960c Ermal Luçi
		return;
250
	}
251
252 37a53d16 Scott Ullrich
	/* make sure the parent interface is up */
253 07101b63 Ermal Luçi
	interfaces_bring_up($if);
254
	/* Since we are going to add vlan(4) try to enable all that hardware supports. */
255 871768cf Ermal
	pfSense_interface_capabilities($if, IFCAP_VLAN_HWTAGGING|IFCAP_VLAN_MTU|IFCAP_VLAN_HWFILTER);
256 cfc707f7 Scott Ullrich
257 4aca19b3 Scott Ullrich
	if (!empty($vlanif) && does_interface_exist($vlanif)) {
258 df2a0f18 Ermal
		interface_bring_down($vlanif, true);
259 4aca19b3 Scott Ullrich
	} else {
260 871768cf Ermal
		$tmpvlanif = pfSense_interface_create("vlan");
261
		pfSense_interface_rename($tmpvlanif, $vlanif);
262
		pfSense_ngctl_name("{$tmpvlanif}:", $vlanif);
263 abcb2bed Ermal Lu?i
	}
264 871768cf Ermal
265
	pfSense_vlan_create($vlanif, $if, $tag);
266 2075fadb Ermal Luçi
267 07101b63 Ermal Luçi
	interfaces_bring_up($vlanif);
268 cfc707f7 Scott Ullrich
269 40b0b541 Ermal Lu?i
	/* invalidate interface cache */
270
	get_interface_arr(true);
271 3f7d2120 Bill Marquette
272 4aca19b3 Scott Ullrich
	/* XXX: ermal -- for now leave it here at the moment it does not hurt. */
273 07101b63 Ermal Luçi
	interfaces_bring_up($if);
274 cfc707f7 Scott Ullrich
275 4aca19b3 Scott Ullrich
	return $vlanif;
276 5b237745 Scott Ullrich
}
277
278 abcb2bed Ermal Lu?i
function interface_qinq_configure(&$vlan, $fd = NULL) {
279 1c3ddd9e Renato Botelho
	global $config, $g;
280
281
	if (!is_array($vlan)) {
282
		log_error(sprintf(gettext("QinQ compat VLAN: called with wrong options. Problems with config!%s"), "\n"));
283
		return;
284
	}
285
286
	$qinqif = $vlan['if'];
287
	$tag = $vlan['tag'];
288
	if(empty($qinqif)) {
289
		log_error(sprintf(gettext("interface_qinq_configure called with if undefined.%s"), "\n"));
290
		return;
291
	}
292 782e33f8 Renato Botelho
293
	if(!does_interface_exist($qinqif)) {
294
		log_error(sprintf(gettext("interface_qinq_configure called with invalid if.%s"), "\n"));
295
		return;
296
	}
297
298 4400ad66 Ermal Lu?i
	$vlanif = interface_vlan_configure($vlan);
299 5f1e1d26 Ermal Lu?i
300 1c3ddd9e Renato Botelho
	if ($fd == NULL) {
301
		$exec = true;
302
		$fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
303
	} else
304
		$exec = false;
305
	/* make sure the parent is converted to ng_vlan(4) and is up */
306
	interfaces_bring_up($qinqif);
307 5f1e1d26 Ermal Lu?i
308 9cf46050 Ermal
	pfSense_ngctl_attach(".", $qinqif);
309 1c3ddd9e Renato Botelho
	if (!empty($vlanif) && does_interface_exist($vlanif)) {
310
		fwrite($fd, "shutdown {$qinqif}qinq:\n");
311
		exec("/usr/sbin/ngctl msg {$qinqif}qinq: gettable", $result);
312
		if (empty($result)) {
313
			fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
314
			fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
315
			fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
316
		}
317
	} else {
318
		fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
319
		fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
320
		fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
321
	}
322
323
	/* invalidate interface cache */
324
	get_interface_arr(true);
325
326 76254caa Renato Botelho
	if (!stristr($qinqif, "_vlan"))
327 1c3ddd9e Renato Botelho
		mwexec("/sbin/ifconfig {$qinqif} promisc\n");
328
329
	$macaddr = get_interface_mac($qinqif);
330
	if (!empty($vlan['members'])) {
331
		$members = explode(" ", $vlan['members']);
332
		foreach ($members as $qtag) {
333
			$qinq = array();
334
			$qinq['tag'] = $qtag;
335
			$qinq['if'] = $vlanif;
336
			interface_qinq2_configure($qinq, $fd, $macaddr);
337
		}
338
	}
339
	if ($exec == true) {
340
		fclose($fd);
341
		mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
342
	}
343
344
	interfaces_bring_up($qinqif);
345
	if (!empty($vlan['members'])) {
346
		$members = explode(" ", $vlan['members']);
347
		foreach ($members as $qif)
348
			interfaces_bring_up("{$vlanif}_{$qif}");
349
	}
350
351
	return $vlanif;
352 5f1e1d26 Ermal Lu?i
}
353
354
function interfaces_qinq_configure() {
355 7a6f7c55 Scott Ullrich
	global $config, $g;
356
	if($g['booting'])
357 07e40c1f Carlos Eduardo Ramos
		echo gettext("Configuring QinQ interfaces...");
358 7a6f7c55 Scott Ullrich
	if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
359
		foreach ($config['qinqs']['qinqentry'] as $qinq) {
360
			/* XXX: Maybe we should report any errors?! */
361 4400ad66 Ermal Lu?i
			interface_qinq_configure($qinq);
362 7a6f7c55 Scott Ullrich
		}
363 4400ad66 Ermal Lu?i
	}
364
	if($g['booting'])
365 07e40c1f Carlos Eduardo Ramos
		echo gettext( "done.") . "\n";
366 5f1e1d26 Ermal Lu?i
}
367
368 abcb2bed Ermal Lu?i
function interface_qinq2_configure(&$qinq, $fd, $macaddr) {
369 1c3ddd9e Renato Botelho
	global $config, $g;
370
371
	if (!is_array($qinq)) {
372
		log_error(sprintf(gettext("QinQ compat VLAN: called with wrong options. Problems with config!%s"), "\n"));
373
		return;
374
	}
375
376
	$if = $qinq['if'];
377
	$tag = $qinq['tag'];
378
	$vlanif = "{$if}_{$tag}";
379
	if(empty($if)) {
380
		log_error(sprintf(gettext("interface_qinq2_configure called with if undefined.%s"), "\n"));
381
		return;
382
	}
383
384
	fwrite($fd, "shutdown {$if}h{$tag}:\n");
385
	fwrite($fd, "mkpeer {$if}qinq: eiface {$if}{$tag} ether\n");
386
	fwrite($fd, "name {$if}qinq:{$if}{$tag} {$if}h{$tag}\n");
387
	fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"{$if}{$tag}\" }\n");
388
	fwrite($fd, "msg {$if}h{$tag}: setifname \"{$vlanif}\"\n");
389
	fwrite($fd, "msg {$if}h{$tag}: set {$macaddr}\n");
390
391
	/* invalidate interface cache */
392
	get_interface_arr(true);
393
394
	return $vlanif;
395 5f1e1d26 Ermal Lu?i
}
396
397 9f428275 Erik Fonnesbeck
function interfaces_create_wireless_clones() {
398 7bb09580 Erik Fonnesbeck
	global $config, $g;
399 9f428275 Erik Fonnesbeck
400
	if($g['booting'])
401 7bb09580 Erik Fonnesbeck
		echo gettext("Creating wireless clone interfaces...");
402
403
	$iflist = get_configured_interface_list();
404
405 0fbf7315 Ermal
	foreach ($iflist as $if) {
406 7bb09580 Erik Fonnesbeck
		$realif = $config['interfaces'][$if]['if'];
407
		if (is_interface_wireless($realif))
408
			interface_wireless_clone(interface_get_wireless_clone($realif), $config['interfaces'][$if]);
409
	}
410
411 6ef2297b Erik Fonnesbeck
	if (isset($config['wireless']['clone']) && is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
412 9f428275 Erik Fonnesbeck
		foreach ($config['wireless']['clone'] as $clone) {
413
			if(empty($clone['cloneif']))
414
				continue;
415
			if(does_interface_exist($clone['cloneif']))
416
				continue;
417
			/* XXX: Maybe we should report any errors?! */
418 7bb09580 Erik Fonnesbeck
			interface_wireless_clone($clone['cloneif'], $clone);
419 9f428275 Erik Fonnesbeck
		}
420
	}
421
	if($g['booting'])
422 7bb09580 Erik Fonnesbeck
		echo gettext("done.") . "\n";
423 a687f866 Namezero
424 9f428275 Erik Fonnesbeck
}
425
426 d7f1891b Ermal
function interfaces_bridge_configure($checkmember = 0) {
427 1c3ddd9e Renato Botelho
	global $config;
428
429
	$i = 0;
430
	if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
431
		foreach ($config['bridges']['bridged'] as $bridge) {
432
			if(empty($bridge['bridgeif']))
433
				$bridge['bridgeif'] = "bridge{$i}";
434 ef1c048b Ermal
			if ($checkmember == 1) {
435
				$members = explode(',', $bridge['members']);
436
				foreach ($members as $member) {
437
					if (strstr($bridge['if'], "_vip"))
438
						continue 2;
439 a8f5790a Renato Botelho
					if (!empty($config['interfaces'][$bridge['if']]) && $config['interfaces'][$bridge['if']]['ipaddrv6'] == "track6")
440 ef1c048b Ermal
						continue 2;
441
				}
442
			}
443
			else if ($checkmember == 2) {
444
				$members = explode(',', $bridge['members']);
445
				foreach ($members as $member) {
446
					if (!strstr($bridge['if'], "_vip"))
447
						continue 2;
448 a8f5790a Renato Botelho
					if (empty($config['interfaces'][$bridge['if']]) || $config['interfaces'][$bridge['if']]['ipaddrv6'] != "track6")
449 ef1c048b Ermal
						continue 2;
450
				}
451
			}
452 1c3ddd9e Renato Botelho
			/* XXX: Maybe we should report any errors?! */
453
			interface_bridge_configure($bridge, $checkmember);
454
			$i++;
455
		}
456
	}
457 bad29bc6 Ermal Luçi
}
458
459 02de5c07 Ermal
function interface_bridge_configure(&$bridge, $checkmember = 0) {
460 d7147b1c Scott Ullrich
	global $config, $g;
461 bad29bc6 Ermal Luçi
462 d7147b1c Scott Ullrich
	if (!is_array($bridge))
463 0e0002c2 bcyrill
		return;
464 bad29bc6 Ermal Luçi
465 dc97efaf Ermal Luçi
	if (empty($bridge['members'])) {
466 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("No members found on %s"), $bridge['bridgeif']));
467 0e0002c2 bcyrill
		return;
468 dc97efaf Ermal Luçi
	}
469
470 bad29bc6 Ermal Luçi
	$members = explode(',', $bridge['members']);
471 70720671 Ermal Luçi
	if (!count($members))
472 0e0002c2 bcyrill
		return;
473 ea5f6c95 Ermal
474 b64523c1 Ermal Luçi
	/* Calculate smaller mtu and enforce it */
475 69e53ef0 Ermal Luçi
	$smallermtu = 0;
476 07676e36 Ermal
	$commonrx = true;
477
	$commontx = true;
478 02de5c07 Ermal
	$foundgif = false;
479 b64523c1 Ermal Luçi
	foreach ($members as $member) {
480
		$realif = get_real_interface($member);
481 07676e36 Ermal
		$opts = pfSense_get_interface_addresses($realif);
482
		$mtu = $opts['mtu'];
483 02de5c07 Ermal
		if (substr($realif, 0, 3) == "gif") {
484
			$foundgif = true;
485
			if ($checkmember == 1)
486
				return;
487
			if ($mtu <= 1500)
488
				continue;
489
		}
490 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['txcsum']))
491 07676e36 Ermal
			$commontx = false;
492 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['rxcsum']))
493 07676e36 Ermal
			$commonrx = false;
494 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['tso4']))
495 0ac206f9 Ermal
			$commontso4 = false;
496 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['tso6']))
497 0ac206f9 Ermal
			$commontso6 = false;
498 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['lro']))
499 0ac206f9 Ermal
			$commonlro = false;
500 69e53ef0 Ermal Luçi
		if ($smallermtu == 0 && !empty($mtu))
501
			$smallermtu = $mtu;
502
		else if (!empty($mtu) && $mtu < $smallermtu)
503 b64523c1 Ermal Luçi
			$smallermtu = $mtu;
504
	}
505 02de5c07 Ermal
	if ($foundgif == false && $checkmember == 2)
506
		return;
507
508 69e53ef0 Ermal Luçi
	/* Just in case anything is not working well */
509
	if ($smallermtu == 0)
510 be45aa79 Renato Botelho
		$smallermtu = 1500;
511 69e53ef0 Ermal Luçi
512 a2dc7392 Renato Botelho
	$flags_on = 0;
513
	$flags_off = 0;
514
	if (isset($config['system']['disablechecksumoffloading']) || ($commonrx === false))
515
		$flags_off |= IFCAP_RXCSUM;
516
	else
517
		$flags_on |= IFCAP_RXCSUM;
518
	if (isset($config['system']['disablechecksumoffloading']) || ($commontx === false))
519
		$flags_off |= IFCAP_TXCSUM;
520
	else
521
		$flags_on |= IFCAP_TXCSUM;
522
	if (isset($config['system']['disablesegmentationoffloading']) || ($commontso4 === false))
523
		$flags_off |= IFCAP_TSO4;
524
	else
525
		$flags_on |= IFCAP_TSO4;
526
	if (isset($config['system']['disablesegmentationoffloading']) || ($commontso6 === false))
527
		$flags_off |= IFCAP_TSO6;
528
	else
529
		$flags_on |= IFCAP_TSO6;
530
	if (isset($config['system']['disablelargereceiveoffloading']) || ($commonlro === false))
531
		$flags_off |= IFCAP_LRO;
532
	else
533
		$flags_on |= IFCAP_LRO;
534 02de5c07 Ermal
535
	if ($g['booting'] || !empty($bridge['bridgeif'])) {
536
		pfSense_interface_destroy($bridge['bridgeif']);
537
		pfSense_interface_create($bridge['bridgeif']);
538 b3af5453 Renato Botelho
		$bridgeif = escapeshellarg($bridge['bridgeif']);
539 6d53bbb5 Ermal
	} else {
540 02de5c07 Ermal
		$bridgeif = pfSense_interface_create("bridge");
541 6d53bbb5 Ermal
		$bridge['bridgeif'] = $bridgeif;
542
	}
543 02de5c07 Ermal
544
	$checklist = get_configured_interface_list();
545
546 bad29bc6 Ermal Luçi
	/* Add interfaces to bridge */
547 31241000 Ermal Luçi
	foreach ($members as $member) {
548 19defb88 Ermal
		if (empty($checklist[$member]))
549 d7147b1c Scott Ullrich
			continue;
550 19defb88 Ermal
		$realif = get_real_interface($member);
551 07676e36 Ermal
		if (!$realif) {
552 07e40c1f Carlos Eduardo Ramos
			log_error(gettext("realif not defined in interfaces bridge - up"));
553 07676e36 Ermal
			continue;
554
		}
555
		/* make sure the parent interface is up */
556 19defb88 Ermal
		pfSense_interface_mtu($realif, $smallermtu);
557 a2dc7392 Renato Botelho
		pfSense_interface_capabilities($realif, -$flags_off);
558
		pfSense_interface_capabilities($realif, $flags_on);
559 19defb88 Ermal
		interfaces_bring_up($realif);
560 6d53bbb5 Ermal
		pfSense_bridge_add_member($bridge['bridgeif'], $realif);
561 d7147b1c Scott Ullrich
	}
562 31241000 Ermal Luçi
563 bad29bc6 Ermal Luçi
	if (isset($bridge['enablestp'])) {
564
		/* Choose spanning tree proto */
565 b3af5453 Renato Botelho
		mwexec("/sbin/ifconfig {$bridgeif} proto " . escapeshellarg($bridge['proto']));
566 be45aa79 Renato Botelho
567 dc97efaf Ermal Luçi
		if (!empty($bridge['stp'])) {
568
			$stpifs = explode(',', $bridge['stp']);
569
			foreach ($stpifs as $stpif) {
570
				$realif = get_real_interface($stpif);
571
				mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
572
			}
573 bad29bc6 Ermal Luçi
		}
574 dc97efaf Ermal Luçi
		if (!empty($bridge['maxage']))
575 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} maxage " . escapeshellarg($bridge['maxage']));
576 a5571287 Chris Buechler
		if (!empty($bridge['fwdelay']))
577 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay " . escapeshellarg($bridge['fwdelay']));
578 a5571287 Chris Buechler
		if (!empty($bridge['hellotime']))
579 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} hellotime " . escapeshellarg($bridge['hellotime']));
580 a5571287 Chris Buechler
		if (!empty($bridge['priority']))
581 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} priority " . escapeshellarg($bridge['priority']));
582 afd825a7 bcyrill
		if (!empty($bridge['holdcnt']))
583 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} holdcnt " . escapeshellarg($bridge['holdcnt']));
584 dc97efaf Ermal Luçi
		if (!empty($bridge['ifpriority'])) {
585
			$pconfig = explode(",", $bridge['ifpriority']);
586
			$ifpriority = array();
587
			foreach ($pconfig as $cfg) {
588 9a456170 Darren Embry
				$embcfg = explode_assoc(":", $cfg);
589 dc97efaf Ermal Luçi
				foreach ($embcfg as $key => $value)
590
					$ifpriority[$key] = $value;
591
			}
592
			foreach ($ifpriority as $key => $value) {
593
				$realif = get_real_interface($key);
594 b3af5453 Renato Botelho
				mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} " . escapeshellarg($value));
595 dc97efaf Ermal Luçi
			}
596 bad29bc6 Ermal Luçi
		}
597 dc97efaf Ermal Luçi
		if (!empty($bridge['ifpathcost'])) {
598 da5895bb Darren Embry
			$pconfig = explode(",", $bridge['ifpathcost']);
599 dc97efaf Ermal Luçi
			$ifpathcost = array();
600
			foreach ($pconfig as $cfg) {
601 9a456170 Darren Embry
				$embcfg = explode_assoc(":", $cfg);
602 dc97efaf Ermal Luçi
				foreach ($embcfg as $key => $value)
603
					$ifpathcost[$key] = $value;
604
			}
605
			foreach ($ifpathcost as $key => $value) {
606 1c3ddd9e Renato Botelho
				$realif = get_real_interface($key);
607 b3af5453 Renato Botelho
				mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} " . escapeshellarg($value));
608 1c3ddd9e Renato Botelho
			}
609 bad29bc6 Ermal Luçi
		}
610
	}
611
612
	if ($bridge['maxaddr'] <> "")
613
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
614 1c3ddd9e Renato Botelho
	if ($bridge['timeout'] <> "")
615
		mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
616
	if ($bridge['span'] <> "") {
617 85a5da13 Ermal Luçi
		$realif = get_real_interface($bridge['span']);
618 1c3ddd9e Renato Botelho
		mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
619 bad29bc6 Ermal Luçi
	}
620 a47a5798 Ermal Luçi
	if (!empty($bridge['edge'])) {
621 1c3ddd9e Renato Botelho
		$edgeifs = explode(',', $bridge['edge']);
622
		foreach ($edgeifs as $edgeif) {
623 a47a5798 Ermal Luçi
			$realif = get_real_interface($edgeif);
624 1c3ddd9e Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
625
		}
626 a47a5798 Ermal Luçi
	}
627
	if (!empty($bridge['autoedge'])) {
628 1c3ddd9e Renato Botelho
		$edgeifs = explode(',', $bridge['autoedge']);
629
		foreach ($edgeifs as $edgeif) {
630
			$realif = get_real_interface($edgeif);
631
			mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
632
		}
633 a47a5798 Ermal Luçi
	}
634
	if (!empty($bridge['ptp'])) {
635 1c3ddd9e Renato Botelho
		$ptpifs = explode(',', $bridge['ptp']);
636
		foreach ($ptpifs as $ptpif) {
637
			$realif = get_real_interface($ptpif);
638
			mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
639
		}
640 a47a5798 Ermal Luçi
	}
641
	if (!empty($bridge['autoptp'])) {
642 1c3ddd9e Renato Botelho
		$ptpifs = explode(',', $bridge['autoptp']);
643
		foreach ($ptpifs as $ptpif) {
644
			$realif = get_real_interface($ptpif);
645
			mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
646
		}
647 a47a5798 Ermal Luçi
	}
648
	if (!empty($bridge['static'])) {
649 1c3ddd9e Renato Botelho
		$stickyifs = explode(',', $bridge['static']);
650
		foreach ($stickyifs as $stickyif) {
651
			$realif = get_real_interface($stickyif);
652
			mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
653
		}
654 a47a5798 Ermal Luçi
	}
655
	if (!empty($bridge['private'])) {
656 1c3ddd9e Renato Botelho
		$privateifs = explode(',', $bridge['private']);
657
		foreach ($privateifs as $privateif) {
658
			$realif = get_real_interface($privateif);
659
			mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
660
		}
661 a47a5798 Ermal Luçi
	}
662 bad29bc6 Ermal Luçi
663 792bdf7f bcyrill
	if ($bridge['bridgeif'])
664 6d53bbb5 Ermal
		interfaces_bring_up($bridge['bridgeif']);
665 be45aa79 Renato Botelho
	else
666 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("bridgeif not defined -- could not bring interface up"));
667 bad29bc6 Ermal Luçi
}
668
669 fcd4a425 Ermal Lu?i
function interface_bridge_add_member($bridgeif, $interface) {
670
671
	if (!does_interface_exist($bridgeif) || !does_interface_exist($interface))
672
		return;
673
674 a5571287 Chris Buechler
	$mtu = get_interface_mtu($bridgeif);
675 fcd4a425 Ermal Lu?i
	$mtum = get_interface_mtu($interface);
676 be45aa79 Renato Botelho
677 73481ad3 Ermal
	if ($mtu != $mtum && !(substr($interface, 0, 3) == "gif" && $mtu <= 1500))
678 871768cf Ermal
		pfSense_interface_mtu($interface, $mtu);
679 fcd4a425 Ermal Lu?i
680 0c77c314 Ermal
	$options = pfSense_get_interface_addresses($bridgeif);
681 a2dc7392 Renato Botelho
	$flags_on = 0;
682
	$flags_off = 0;
683
	if (isset($options['encaps']['txcsum']))
684
		$flags_on |= IFCAP_TXCSUM;
685
	else
686
		$flags_off |= IFCAP_TXCSUM;
687
	if (isset($options['encaps']['rxcsum']))
688
		$flags_on |= IFCAP_RXCSUM;
689
	else
690
		$flags_off |= IFCAP_RXCSUM;
691
	if (isset($options['encaps']['tso4']))
692
		$flags_on |= IFCAP_TSO4;
693
	else
694
		$flags_off |= IFCAP_TSO4;
695
	if (isset($options['encaps']['tso6']))
696
		$flags_on |= IFCAP_TSO6;
697
	else
698
		$flags_off |= IFCAP_TSO6;
699
	if (isset($options['encaps']['lro']))
700
		$flags_on |= IFCAP_LRO;
701
	else
702
		$flags_off |= IFCAP_LRO;
703 51d5aad7 Ermal
704 a2dc7392 Renato Botelho
	pfSense_interface_capabilities($interface, -$flags_off);
705
	pfSense_interface_capabilities($interface, $flags_on);
706 3ca774ac Ermal
707 fcd4a425 Ermal Lu?i
	interfaces_bring_up($interface);
708 2064fa2e Ermal
	pfSense_bridge_add_member($bridgeif, $interface);
709 fcd4a425 Ermal Lu?i
}
710
711 1c3ddd9e Renato Botelho
function interfaces_lagg_configure() {
712
	global $config, $g;
713
	if($g['booting'])
714
		echo gettext("Configuring LAGG interfaces...");
715
	$i = 0;
716
	if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
717
		foreach ($config['laggs']['lagg'] as $lagg) {
718
			if(empty($lagg['laggif']))
719
				$lagg['laggif'] = "lagg{$i}";
720
			/* XXX: Maybe we should report any errors?! */
721
			interface_lagg_configure($lagg);
722
			$i++;
723 7a6f7c55 Scott Ullrich
		}
724 1c3ddd9e Renato Botelho
	}
725
	if($g['booting'])
726
		echo gettext("done.") . "\n";
727 cccf624b Ermal Luçi
}
728
729 eba938e3 Scott Ullrich
function interface_lagg_configure(&$lagg) {
730 1c3ddd9e Renato Botelho
	global $config, $g;
731 cccf624b Ermal Luçi
732 1c3ddd9e Renato Botelho
	if (!is_array($lagg))
733 cccf624b Ermal Luçi
		return -1;
734
735
	$members = explode(',', $lagg['members']);
736
	if (!count($members))
737
		return -1;
738 be45aa79 Renato Botelho
739 b64523c1 Ermal Luçi
	if ($g['booting'] || !(empty($lagg['laggif']))) {
740 871768cf Ermal
		pfSense_interface_destroy($lagg['laggif']);
741
		pfSense_interface_create($lagg['laggif']);
742 1c3ddd9e Renato Botelho
		$laggif = $lagg['laggif'];
743
	} else
744 871768cf Ermal
		$laggif = pfSense_interface_create("lagg");
745 b64523c1 Ermal Luçi
746
	/* Calculate smaller mtu and enforce it */
747 1c3ddd9e Renato Botelho
	$smallermtu = 0;
748
	foreach ($members as $member) {
749 0ac206f9 Ermal
		$opts = pfSense_get_interface_addresses($member);
750 1c3ddd9e Renato Botelho
		$mtu = $opts['mtu'];
751 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['txcsum']))
752 1c3ddd9e Renato Botelho
			$commontx = false;
753 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['rxcsum']))
754 1c3ddd9e Renato Botelho
			$commonrx = false;
755 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['tso4']))
756 0ac206f9 Ermal
			$commontso4 = false;
757 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['tso6']))
758 0ac206f9 Ermal
			$commontso6 = false;
759 a2dc7392 Renato Botelho
		if (!isset($opts['caps']['lro']))
760 0ac206f9 Ermal
			$commonlro = false;
761 69e53ef0 Ermal Luçi
		if ($smallermtu == 0 && !empty($mtu))
762
			$smallermtu = $mtu;
763 1c3ddd9e Renato Botelho
		else if (!empty($mtu) && $mtu < $smallermtu)
764
			$smallermtu = $mtu;
765
	}
766 b64523c1 Ermal Luçi
767 69e53ef0 Ermal Luçi
	/* Just in case anything is not working well */
768 1c3ddd9e Renato Botelho
	if ($smallermtu == 0)
769
		$smallermtu = 1500;
770 69e53ef0 Ermal Luçi
771 a2dc7392 Renato Botelho
	$flags_on = 0;
772
	$flags_off = 0;
773
	if (isset($config['system']['disablechecksumoffloading']) || ($commonrx === false))
774
		$flags_off |= IFCAP_RXCSUM;
775
	else
776
		$flags_on |= IFCAP_RXCSUM;
777
	if (isset($config['system']['disablechecksumoffloading']) || ($commontx === false))
778
		$flags_off |= IFCAP_TXCSUM;
779
	else
780
		$flags_on |= IFCAP_TXCSUM;
781
	if (isset($config['system']['disablesegmentationoffloading']) || ($commontso4 === false))
782
		$flags_off |= IFCAP_TSO4;
783
	else
784
		$flags_on |= IFCAP_TSO4;
785
	if (isset($config['system']['disablesegmentationoffloading']) || ($commontso6 === false))
786
		$flags_off |= IFCAP_TSO6;
787
	else
788
		$flags_on |= IFCAP_TSO6;
789
	if (isset($config['system']['disablelargereceiveoffloading']) || ($commonlro === false))
790
		$flags_off |= IFCAP_LRO;
791
	else
792
		$flags_on |= IFCAP_LRO;
793 0ac206f9 Ermal
794 02de5c07 Ermal
	$checklist = get_interface_list();
795
796 cccf624b Ermal Luçi
	foreach ($members as $member) {
797
		if (!array_key_exists($member, $checklist))
798
			continue;
799 d7147b1c Scott Ullrich
		/* make sure the parent interface is up */
800 871768cf Ermal
		pfSense_interface_mtu($member, $smallermtu);
801 a2dc7392 Renato Botelho
		pfSense_interface_capabilities($member, -$flags_off);
802
		pfSense_interface_capabilities($member, $flags_on);
803 39fbee97 Ermal Lu?i
		interfaces_bring_up($member);
804 f421cbcc Ermal Lu?i
		mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
805 cccf624b Ermal Luçi
	}
806 be45aa79 Renato Botelho
807 39fbee97 Ermal Lu?i
	mwexec("/sbin/ifconfig {$laggif} laggproto {$lagg['proto']}");
808 acc1e9d0 Scott Ullrich
809 b5b957fe Scott Ullrich
	interfaces_bring_up($laggif);
810 cccf624b Ermal Luçi
811 d7147b1c Scott Ullrich
	return $laggif;
812 cccf624b Ermal Luçi
}
813
814 d7f1891b Ermal
function interfaces_gre_configure($checkparent = 0) {
815 1c3ddd9e Renato Botelho
	global $config;
816 582d2452 Ermal Luçi
817 1c3ddd9e Renato Botelho
	if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
818
		foreach ($config['gres']['gre'] as $i => $gre) {
819
			if(empty($gre['greif']))
820
				$gre['greif'] = "gre{$i}";
821 ef1c048b Ermal
			if ($checkparent == 1) {
822
				if (strstr($gre['if'], "_vip"))
823
					continue;
824 a8f5790a Renato Botelho
				if (!empty($config['interfaces'][$gre['if']]) && $config['interfaces'][$gre['if']]['ipaddrv6'] == "track6")
825 ef1c048b Ermal
					continue;
826
			}
827
			else if ($checkparent == 2) {
828
				if (!strstr($gre['if'], "_vip"))
829
					continue;
830 a8f5790a Renato Botelho
				if (empty($config['interfaces'][$gre['if']]) || $config['interfaces'][$gre['if']]['ipaddrv6'] != "track6")
831 ef1c048b Ermal
					continue;
832
			}
833 1c3ddd9e Renato Botelho
			/* XXX: Maybe we should report any errors?! */
834
			interface_gre_configure($gre);
835
		}
836
	}
837 582d2452 Ermal Luçi
}
838
839 ed62880b Ermal
/* NOTE: $grekey is not used but useful for passing this function to array_walk. */
840
function interface_gre_configure(&$gre, $grekey = "") {
841 1c3ddd9e Renato Botelho
	global $config, $g;
842 582d2452 Ermal Luçi
843
	if (!is_array($gre))
844
		return -1;
845
846 85a5da13 Ermal Luçi
	$realif = get_real_interface($gre['if']);
847
	$realifip = get_interface_ip($gre['if']);
848 582d2452 Ermal Luçi
849 d7147b1c Scott Ullrich
	/* make sure the parent interface is up */
850 b5b957fe Scott Ullrich
	interfaces_bring_up($realif);
851 582d2452 Ermal Luçi
852 d7147b1c Scott Ullrich
	if ($g['booting'] || !(empty($gre['greif']))) {
853 871768cf Ermal
		pfSense_interface_destroy($gre['greif']);
854
		pfSense_interface_create($gre['greif']);
855 582d2452 Ermal Luçi
		$greif = $gre['greif'];
856 871768cf Ermal
	} else
857
		$greif = pfSense_interface_create("gre");
858 582d2452 Ermal Luçi
859
	/* Do not change the order here for more see gre(4) NOTES section. */
860
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
861 a59c7fa6 smos
	if((is_ipaddrv6($gre['tunnel-local-addr'])) || (is_ipaddrv6($gre['tunnel-remote-addr']))) {
862
		mwexec("/sbin/ifconfig {$greif} inet6 {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} prefixlen /{$gre['tunnel-remote-net']} ");
863
	} else {
864 bfede3d4 jim-p
		mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask " . gen_subnet_mask($gre['tunnel-remote-net']));
865 a59c7fa6 smos
	}
866 f8edf05d jim-p
	if (isset($gre['link0']))
867 871768cf Ermal
		pfSense_interface_flags($greif, IFF_LINK0);
868 f8edf05d jim-p
	if (isset($gre['link1']))
869 871768cf Ermal
		pfSense_interface_flags($greif, IFF_LINK1);
870 f8edf05d jim-p
	if (isset($gre['link2']))
871 871768cf Ermal
		pfSense_interface_flags($greif, IFF_LINK2);
872 d7147b1c Scott Ullrich
873
	if($greif)
874 b5b957fe Scott Ullrich
		interfaces_bring_up($greif);
875 be45aa79 Renato Botelho
	else
876 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("Could not bring greif up -- variable not defined."));
877 582d2452 Ermal Luçi
878 53b0d9d3 Ermal Lu?i
	if (isset($gre['link1']) && $gre['link1'])
879 61b67ab3 Ermal Lu?i
		mwexec("/sbin/route add {$gre['tunnel-remote-addr']}/{$gre['tunnel-remote-net']} {$gre['tunnel-local-addr']}");
880 283e9180 Seth Mos
	if(is_ipaddrv4($gre['tunnel-remote-addr']))
881
		file_put_contents("{$g['tmp_path']}/{$greif}_router", $gre['tunnel-remote-addr']);
882
	if(is_ipaddrv6($gre['tunnel-remote-addr']))
883
		file_put_contents("{$g['tmp_path']}/{$greif}_routerv6", $gre['tunnel-remote-addr']);
884 582d2452 Ermal Luçi
885
	return $greif;
886
}
887
888 d7f1891b Ermal
function interfaces_gif_configure($checkparent = 0) {
889 9006e9f8 Scott Ullrich
	global $config;
890 f1a93dee Ermal
891 9006e9f8 Scott Ullrich
	if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
892 f1a93dee Ermal
		foreach ($config['gifs']['gif'] as $i => $gif) {
893 9006e9f8 Scott Ullrich
			if(empty($gif['gifif']))
894
				$gre['gifif'] = "gif{$i}";
895 ef1c048b Ermal
			if ($checkparent == 1) {
896
				if (strstr($gif['if'], "_vip"))
897
					continue;
898 a8f5790a Renato Botelho
				if (!empty($config['interfaces'][$gif['if']]) && $config['interfaces'][$gif['if']]['ipaddrv6'] == "track6")
899 ef1c048b Ermal
					continue;
900
			}
901
			else if ($checkparent == 2) {
902
				if (!strstr($gre['if'], "_vip"))
903
					continue;
904 a8f5790a Renato Botelho
				if (empty($config['interfaces'][$gif['if']]) || $config['interfaces'][$gif['if']]['ipaddrv6'] != "track6")
905 ef1c048b Ermal
					continue;
906
			}
907 9006e9f8 Scott Ullrich
			/* XXX: Maybe we should report any errors?! */
908
			interface_gif_configure($gif);
909
		}
910
	}
911 582d2452 Ermal Luçi
}
912
913 ed62880b Ermal
/* NOTE: $gifkey is not used but useful for passing this function to array_walk. */
914
function interface_gif_configure(&$gif, $gifkey = "") {
915 9006e9f8 Scott Ullrich
	global $config, $g;
916 582d2452 Ermal Luçi
917 9006e9f8 Scott Ullrich
	if (!is_array($gif))
918
		return -1;
919 582d2452 Ermal Luçi
920 9006e9f8 Scott Ullrich
	$realif = get_real_interface($gif['if']);
921 8436caa7 bcyrill
	$ipaddr = $gif['ipaddr'];
922 582d2452 Ermal Luçi
923 8436caa7 bcyrill
	if (is_ipaddrv4($gif['remote-addr'])) {
924
		if (is_ipaddrv4($ipaddr))
925
			$realifip = $ipaddr;
926
		else
927
			$realifip = get_interface_ip($gif['if']);
928 01a58d89 smos
		$realifgw = get_interface_gateway($gif['if']);
929 8436caa7 bcyrill
	} else if (is_ipaddrv6($gif['remote-addr'])) {
930
		if (is_ipaddrv6($ipaddr))
931
			$realifip = $ipaddr;
932
		else
933
			$realifip = get_interface_ipv6($gif['if']);
934 01a58d89 smos
		$realifgw = get_interface_gatewayv6($gif['if']);
935
	}
936 9006e9f8 Scott Ullrich
	/* make sure the parent interface is up */
937
	if($realif)
938
		interfaces_bring_up($realif);
939 be45aa79 Renato Botelho
	else
940 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("could not bring realif up -- variable not defined -- interface_gif_configure()"));
941 582d2452 Ermal Luçi
942 9006e9f8 Scott Ullrich
	if ($g['booting'] || !(empty($gif['gifif']))) {
943 871768cf Ermal
		pfSense_interface_destroy($gif['gifif']);
944
		pfSense_interface_create($gif['gifif']);
945 9006e9f8 Scott Ullrich
		$gifif = $gif['gifif'];
946
	} else
947 871768cf Ermal
		$gifif = pfSense_interface_create("gif");
948 9006e9f8 Scott Ullrich
949
	/* Do not change the order here for more see gif(4) NOTES section. */
950
	mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
951 9b1ff028 Seth Mos
	if((is_ipaddrv6($gif['tunnel-local-addr'])) || (is_ipaddrv6($gif['tunnel-remote-addr']))) {
952 5a8371cd smos
		mwexec("/sbin/ifconfig {$gifif} inet6 {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} prefixlen /{$gif['tunnel-remote-net']} ");
953 9b1ff028 Seth Mos
	} else {
954
		mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net']));
955
	}
956 f8edf05d jim-p
	if (isset($gif['link0']))
957 871768cf Ermal
		pfSense_interface_flags($gifif, IFF_LINK0);
958 f8edf05d jim-p
	if (isset($gif['link1']))
959 871768cf Ermal
		pfSense_interface_flags($gifif, IFF_LINK1);
960 9006e9f8 Scott Ullrich
	if($gifif)
961
		interfaces_bring_up($gifif);
962
	else
963 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("could not bring gifif up -- variable not defined"));
964 9006e9f8 Scott Ullrich
965 7c0571ce Seth Mos
	$iflist = get_configured_interface_list();
966
	foreach($iflist as $ifname) {
967
		if($config['interfaces'][$ifname]['if'] == $gifif) {
968 e2b6e604 Seth Mos
			if(get_interface_gateway($ifname)) {
969
				system_routing_configure($ifname);
970
				break;
971
			}
972 7c0571ce Seth Mos
			if(get_interface_gateway_v6($ifname)) {
973
				system_routing_configure($ifname);
974
				break;
975
			}
976
		}
977
	}
978 283e9180 Seth Mos
979 a687f866 Namezero
980 283e9180 Seth Mos
	if(is_ipaddrv4($gif['tunnel-remote-addr']))
981
		file_put_contents("{$g['tmp_path']}/{$gifif}_router", $gif['tunnel-remote-addr']);
982
	if(is_ipaddrv6($gif['tunnel-remote-addr']))
983
		file_put_contents("{$g['tmp_path']}/{$gifif}_routerv6", $gif['tunnel-remote-addr']);
984 582d2452 Ermal Luçi
985 1c3ddd9e Renato Botelho
	if (is_ipaddrv4($realifgw)) {
986 85a389c9 Ermal
		mwexec("/sbin/route change -host {$gif['remote-addr']} {$realifgw}");
987 1c3ddd9e Renato Botelho
	}
988
	if (is_ipaddrv6($realifgw)) {
989 85a389c9 Ermal
		mwexec("/sbin/route change -host -inet6 {$gif['remote-addr']} {$realifgw}");
990 1c3ddd9e Renato Botelho
	}
991 01a58d89 smos
992 9006e9f8 Scott Ullrich
	return $gifif;
993 582d2452 Ermal Luçi
}
994
995 eba938e3 Scott Ullrich
function interfaces_configure() {
996 9b1c39e3 Ermal Luçi
	global $config, $g;
997
998 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
999
		return;
1000
1001 a5d6f60b Ermal Lu?i
	/* Set up our loopback interface */
1002 4aca19b3 Scott Ullrich
	interfaces_loopback_configure();
1003 a5d6f60b Ermal Lu?i
1004 f3bddb47 Ermal
	/* create the unconfigured wireless clones */
1005
	interfaces_create_wireless_clones();
1006
1007 541b7c56 Scott Ullrich
	/* set up LAGG virtual interfaces */
1008
	interfaces_lagg_configure();
1009
1010 acc1e9d0 Scott Ullrich
	/* set up VLAN virtual interfaces */
1011
	interfaces_vlan_configure();
1012
1013 5f1e1d26 Ermal Lu?i
	interfaces_qinq_configure();
1014
1015 67ee1ec5 Ermal Luçi
	$iflist = get_configured_interface_with_descr();
1016 9b1c39e3 Ermal Luçi
	$delayed_list = array();
1017
	$bridge_list = array();
1018 ef1c048b Ermal
	$track6_list = array();
1019 be45aa79 Renato Botelho
1020 871768cf Ermal
	/* This is needed to speedup interfaces on bootup. */
1021
	$reload = false;
1022 ae17d2e9 Ermal
	if (!$g['booting'])
1023 871768cf Ermal
		$reload = true;
1024
1025 67ee1ec5 Ermal Luçi
	foreach($iflist as $if => $ifname) {
1026 0dc702f3 Ermal Lu?i
		$realif = $config['interfaces'][$if]['if'];
1027 be45aa79 Renato Botelho
		if (strstr($realif, "bridge"))
1028 9b1c39e3 Ermal Luçi
			$bridge_list[$if] = $ifname;
1029
		else if (strstr($realif, "gre"))
1030
			$delayed_list[$if] = $ifname;
1031
		else if (strstr($realif, "gif"))
1032
			$delayed_list[$if] = $ifname;
1033 d09d53ac Ermal
		else if (strstr($realif, "ovpn")) {
1034
			//echo "Delaying OpenVPN interface configuration...done.\n";
1035
			continue;
1036 a823022d Ermal
		} else if (!empty($config['interfaces'][$if]['ipaddrv6']) && $config['interfaces'][$if]['ipaddrv6'] == "track6") {
1037 3d92cd88 Renato Botelho
			$track6_list[$if] = $ifname;
1038 d09d53ac Ermal
		} else {
1039 9b1c39e3 Ermal Luçi
			if ($g['booting'])
1040 07e40c1f Carlos Eduardo Ramos
				printf(gettext("Configuring %s interface..."), $ifname);
1041 a687f866 Namezero
1042 9006e9f8 Scott Ullrich
			if($g['debug'])
1043 07e40c1f Carlos Eduardo Ramos
				log_error(sprintf(gettext("Configuring %s"), $ifname));
1044 871768cf Ermal
			interface_configure($if, $reload);
1045 be45aa79 Renato Botelho
			if ($g['booting'])
1046 07e40c1f Carlos Eduardo Ramos
				echo gettext( "done.") . "\n";
1047 9b1c39e3 Ermal Luçi
		}
1048
	}
1049
1050 d7f1891b Ermal
	/*
1051
	 * NOTE: The following function parameter consists of
1052
	 *	1 - Do not load gre/gif/bridge with parent/member as vip
1053
	 *	2 - Do load gre/gif/bridge with parent/member as vip
1054
	 */
1055
1056 d7147b1c Scott Ullrich
	/* set up GRE virtual interfaces */
1057 d7f1891b Ermal
	interfaces_gre_configure(1);
1058 9b1c39e3 Ermal Luçi
1059 d7147b1c Scott Ullrich
	/* set up GIF virtual interfaces */
1060 d7f1891b Ermal
	interfaces_gif_configure(1);
1061
1062
	/* set up BRIDGe virtual interfaces */
1063
	interfaces_bridge_configure(1);
1064
1065 ef1c048b Ermal
	foreach ($track6_list as $if => $ifname) {
1066
		if ($g['booting'])
1067
			printf(gettext("Configuring %s interface..."), $ifname);
1068
		if ($g['debug'])
1069
			log_error(sprintf(gettext("Configuring %s"), $ifname));
1070
1071
		interface_configure($if, $reload);
1072
1073
		if ($g['booting'])
1074
			echo gettext("done.") . "\n";
1075
	}
1076
1077 d7f1891b Ermal
	/* bring up vip interfaces */
1078
	interfaces_vips_configure();
1079
1080
	/* set up GRE virtual interfaces */
1081
	interfaces_gre_configure(2);
1082
1083
	/* set up GIF virtual interfaces */
1084
	interfaces_gif_configure(2);
1085
1086 9b1c39e3 Ermal Luçi
	foreach ($delayed_list as $if => $ifname) {
1087
		if ($g['booting'])
1088 07e40c1f Carlos Eduardo Ramos
			printf(gettext("Configuring %s interface..."), $ifname);
1089 1c3ddd9e Renato Botelho
		if ($g['debug'])
1090
			log_error(sprintf(gettext("Configuring %s"), $ifname));
1091 67ee1ec5 Ermal Luçi
1092 871768cf Ermal
		interface_configure($if, $reload);
1093 4476d447 Ermal Luçi
1094 9b1c39e3 Ermal Luçi
		if ($g['booting'])
1095 07e40c1f Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
1096 67ee1ec5 Ermal Luçi
	}
1097 cfc707f7 Scott Ullrich
1098 d7147b1c Scott Ullrich
	/* set up BRIDGe virtual interfaces */
1099 d7f1891b Ermal
	interfaces_bridge_configure(2);
1100 9b1c39e3 Ermal Luçi
1101 d7147b1c Scott Ullrich
	foreach ($bridge_list as $if => $ifname) {
1102
		if ($g['booting'])
1103 07e40c1f Carlos Eduardo Ramos
			printf(gettext("Configuring %s interface..."), $ifname);
1104 d7147b1c Scott Ullrich
		if($g['debug'])
1105 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Configuring %s"), $ifname));
1106 9b1c39e3 Ermal Luçi
1107 871768cf Ermal
		interface_configure($if, $reload);
1108 9b1c39e3 Ermal Luçi
1109 d7147b1c Scott Ullrich
		if ($g['booting'])
1110 07e40c1f Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
1111 d7147b1c Scott Ullrich
	}
1112 9b1c39e3 Ermal Luçi
1113 42753d25 Ermal Lu?i
	/* configure interface groups */
1114
	interfaces_group_setup();
1115
1116 5b237745 Scott Ullrich
	if (!$g['booting']) {
1117
		/* reconfigure static routes (kernel may have deleted them) */
1118
		system_routing_configure();
1119 cfc707f7 Scott Ullrich
1120 5b237745 Scott Ullrich
		/* reload IPsec tunnels */
1121
		vpn_ipsec_configure();
1122 cfc707f7 Scott Ullrich
1123 f620d00d Ermal Luçi
		/* reload dhcpd (interface enabled/disabled status may have changed) */
1124 5b237745 Scott Ullrich
		services_dhcpd_configure();
1125 cfc707f7 Scott Ullrich
1126 5b237745 Scott Ullrich
		/* restart dnsmasq */
1127
		services_dnsmasq_configure();
1128 4d18de6a Scott Ullrich
1129 c597d50f Scott Ullrich
		/* reload captive portal */
1130 491652bf Ermal
		if (function_exists('captiveportal_init_rules'))
1131
			captiveportal_init_rules();
1132 5b237745 Scott Ullrich
	}
1133 cfc707f7 Scott Ullrich
1134 5b237745 Scott Ullrich
	return 0;
1135
}
1136
1137 7a18dfa4 lgcosta
function interface_reconfigure($interface = "wan", $reloadall = false) {
1138 80bf3f4a Ermal Luçi
	interface_bring_down($interface);
1139 7a18dfa4 lgcosta
	interface_configure($interface, $reloadall);
1140 80bf3f4a Ermal Luçi
}
1141
1142 91a38e1f Ermal
function interface_vip_bring_down($vip) {
1143 962fd685 Ermal
	global $g;
1144
1145 abcb2bed Ermal Lu?i
	switch ($vip['mode']) {
1146
	case "proxyarp":
1147 962fd685 Ermal
		$vipif = get_real_interface($vip['interface']);
1148 ca942829 Ermal
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
1149
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
1150 abcb2bed Ermal Lu?i
		break;
1151
	case "ipalias":
1152 435f11c8 Ermal Lu?i
		$vipif = get_real_interface($vip['interface']);
1153 5918f9b7 Ermal
		if (does_interface_exist($vipif)) {
1154
			if (is_ipaddrv6($vip['subnet']))
1155
				mwexec("/sbin/ifconfig {$vipif} inet6 {$vip['subnet']} -alias");
1156
			else
1157
				pfSense_interface_deladdress($vipif, $vip['subnet']);
1158
		}
1159 abcb2bed Ermal Lu?i
		break;
1160
	case "carp":
1161 7b47bd4c Ermal
		$vipif = "{$vip['interface']}_vip{$vip['vhid']}";
1162 be45aa79 Renato Botelho
		if (does_interface_exist($vipif))
1163 871768cf Ermal
			pfSense_interface_destroy($vipif);
1164 abcb2bed Ermal Lu?i
		break;
1165
	}
1166
}
1167
1168 9343d750 Ermal
function interface_bring_down($interface = "wan", $destroy = false, $ifacecfg = false) {
1169 80bf3f4a Ermal Luçi
	global $config, $g;
1170
1171 99c2a28b Ermal Luçi
	if (!isset($config['interfaces'][$interface]))
1172 be45aa79 Renato Botelho
		return;
1173 203e4bb6 Ermal
1174
	if ($g['debug'])
1175
		log_error("Calling interface down for interface {$interface}, destroy is " . (($destroy) ? 'true' : 'false'));
1176 37fb708c smos
1177 e12ad49f Renato Botelho
	if ($ifacecfg === false) {
1178 9343d750 Ermal
		$ifcfg = $config['interfaces'][$interface];
1179 e12ad49f Renato Botelho
		$ppps = $config['ppps']['ppp'];
1180
		$realif = get_real_interface($interface);
1181
	} elseif (!is_array($ifacecfg)) {
1182 9343d750 Ermal
		log_error(gettext("Wrong parameters used during interface_bring_down"));
1183 e12ad49f Renato Botelho
	} else {
1184
		$ifcfg = $ifacecfg['ifcfg'];
1185
		$ppps = $ifacecfg['ppps'];
1186
		if (isset($ifacecfg['ifcfg']['realif']))
1187
			$realif = $ifacecfg['ifcfg']['realif'];
1188
		else
1189
			$realif = get_real_interface($interface);
1190
	}
1191 80bf3f4a Ermal Luçi
1192
	switch ($ifcfg['ipaddr']) {
1193 0810c115 gnhb
	case "ppp":
1194 80bf3f4a Ermal Luçi
	case "pppoe":
1195
	case "pptp":
1196 39f750b5 gnhb
	case "l2tp":
1197 e12ad49f Renato Botelho
		if (is_array($ppps) && count($ppps)) {
1198
			foreach ($ppps as $pppid => $ppp) {
1199 a138f4fb Ermal
				if ($realif == $ppp['if']) {
1200 c8d23069 gnhb
					if (isset($ppp['ondemand']) && !$destroy){
1201
						send_event("interface reconfigure {$interface}");
1202
						break;
1203
					}
1204 a8d6ac1a Ermal
					if (file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid")) {
1205
						killbypid("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid");
1206 c8d23069 gnhb
						sleep(2);
1207 8d9cbe6f Ermal
					}
1208 64e6490a Ermal
					unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
1209 a138f4fb Ermal
					break;
1210
				}
1211
			}
1212
		}
1213 80bf3f4a Ermal Luçi
		break;
1214
	case "dhcp":
1215 5d478ecc Ermal Lu?i
		$pid = find_dhclient_process($realif);
1216 f07bee94 Scott Ullrich
		if($pid)
1217 deb39cf2 Ermal
			posix_kill($pid, SIGTERM);
1218 37fb708c smos
		sleep(1);
1219
		unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
1220
		if(does_interface_exist("$realif")) {
1221
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
1222
			if ($destroy == true)
1223
				pfSense_interface_flags($realif, -IFF_UP);
1224
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1225
		}
1226
		break;
1227
	default:
1228
		if(does_interface_exist("$realif")) {
1229
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
1230
			if ($destroy == true)
1231
				pfSense_interface_flags($realif, -IFF_UP);
1232
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1233
		}
1234
		break;
1235
	}
1236
1237
	switch ($ifcfg['ipaddrv6']) {
1238 feb88a14 smos
	case "slaac":
1239 37fb708c smos
	case "dhcp6":
1240 c65d3051 Seth Mos
		$pidv6 = find_dhcp6c_process($realif);
1241 c495f88b Seth Mos
		if($pidv6)
1242 82b50e76 Ermal
			posix_kill($pidv6, SIGTERM);
1243 74fa57aa smos
		sleep(3);
1244 c495f88b Seth Mos
		unlink_if_exists("{$g['varetc_path']}/dhcp6c_{$interface}.conf");
1245 e017a46a Ermal
		if (does_interface_exist("$realif")) {
1246 66c73aab Ermal
			$ip6 = get_interface_ipv6($interface);
1247
			if (is_ipaddrv6($ip6))
1248
				mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$ip6} delete", true);
1249 e49a2031 Ermal
			if ($destroy == true)
1250
				pfSense_interface_flags($realif, -IFF_UP);
1251 5630c91c Ermal Lu?i
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1252 f07bee94 Scott Ullrich
		}
1253 80bf3f4a Ermal Luçi
		break;
1254 3f383504 smos
	case "6rd":
1255 31c43fd3 smos
	case "6to4":
1256 7d1f2eac Ermal
		$realif = "{$interface}_stf";
1257 31c43fd3 smos
		if(does_interface_exist("$realif")) {
1258 66c73aab Ermal
			$ip6 = get_interface_ipv6($interface);
1259
			if (is_ipaddrv6($ip6))
1260
				mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$ip6} delete", true);
1261 31c43fd3 smos
			if ($destroy == true)
1262
				pfSense_interface_flags($realif, -IFF_UP);
1263 be45aa79 Renato Botelho
		}
1264 31c43fd3 smos
		break;
1265 80bf3f4a Ermal Luçi
	default:
1266 f07bee94 Scott Ullrich
		if(does_interface_exist("$realif")) {
1267 66c73aab Ermal
			$ip6 = get_interface_ipv6($interface);
1268
			if (is_ipaddrv6($ip6))
1269
				mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$ip6} delete", true);
1270 80fae0e2 Ermal Lu?i
			if (!empty($ifcfg['ipaddrv6']) && is_ipaddrv6($ifcfg['ipaddrv6']))
1271
				mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$ifcfg['ipaddrv6']} delete", true);
1272 e49a2031 Ermal
			if ($destroy == true)
1273
				pfSense_interface_flags($realif, -IFF_UP);
1274 5630c91c Ermal Lu?i
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1275 f07bee94 Scott Ullrich
		}
1276 80bf3f4a Ermal Luçi
		break;
1277
	}
1278 eb772abd Scott Ullrich
1279 97f7a517 jim-p
	if (file_exists("{$g['tmp_path']}/{$realif}_router"))
1280
		$old_router = trim(file_get_contents("{$g['tmp_path']}/{$realif}_router"));
1281 96f7a687 jim-p
//	log_error("Checking for old router states: {$g['tmp_path']}/{$realif}_router = {$old_router}");
1282
	if (!empty($old_router)) {
1283
		log_error("Clearing states to old gateway {$old_router}.");
1284 1befdbf8 Ermal
		mwexec("/sbin/pfctl -i {$realif} -Fs -G {$old_router}");
1285 96f7a687 jim-p
	}
1286 37fb708c smos
1287 73ee49f2 gnhb
	/* remove interface up file if it exists */
1288
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
1289
	unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
1290 c495f88b Seth Mos
	unlink_if_exists("{$g['vardb_path']}/{$interface}ipv6");
1291 73ee49f2 gnhb
	unlink_if_exists("{$g['tmp_path']}/{$realif}_router");
1292 c495f88b Seth Mos
	unlink_if_exists("{$g['tmp_path']}/{$realif}_routerv6");
1293 86dcdfc9 Ermal
	unlink_if_exists("{$g['varetc_path']}/nameserver_{$realif}");
1294
	unlink_if_exists("{$g['varetc_path']}/searchdomain_{$realif}");
1295 be45aa79 Renato Botelho
1296 b5582f49 Erik Fonnesbeck
	/* hostapd and wpa_supplicant do not need to be running when the interface is down.
1297
	 * They will also use 100% CPU if running after the wireless clone gets deleted. */
1298
	if (is_array($ifcfg['wireless'])) {
1299 97f3ce0f Phil Davis
		kill_hostapd($realif);
1300 b5582f49 Erik Fonnesbeck
		mwexec(kill_wpasupplicant($realif));
1301
	}
1302
1303 97973ed8 Ermal Luçi
	if ($destroy == true) {
1304 1e8a05a2 bcyrill
		if (preg_match("/^[a-z0-9]+_vip|^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan|_stf$/i", $realif))
1305 871768cf Ermal
			pfSense_interface_destroy($realif);
1306 be45aa79 Renato Botelho
	}
1307 9006e9f8 Scott Ullrich
1308 80bf3f4a Ermal Luçi
	return;
1309 5b237745 Scott Ullrich
}
1310
1311 e5d558bf gnhb
function interfaces_ptpid_used($ptpid) {
1312
	global $config;
1313
1314
	if (is_array($config['ppps']['ppp']))
1315
		foreach ($config['ppps']['ppp'] as & $settings)
1316
			if ($ptpid == $settings['ptpid'])
1317
				return true;
1318
1319
	return false;
1320
}
1321
1322
function interfaces_ptpid_next() {
1323
1324
	$ptpid = 0;
1325
	while(interfaces_ptpid_used($ptpid))
1326
		$ptpid++;
1327
1328
	return $ptpid;
1329
}
1330
1331 70e46e62 Ermal
function getMPDCRONSettings($pppif) {
1332 e5d558bf gnhb
	global $config;
1333 70e46e62 Ermal
1334
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
1335 e5d558bf gnhb
	if (is_array($config['cron']['item'])) {
1336 70e46e62 Ermal
		foreach ($config['cron']['item'] as $i => $item) {
1337
			if (stripos($item['command'], $cron_cmd_file) !== false)
1338 e5d558bf gnhb
				return array("ID" => $i, "ITEM" => $item);
1339
		}
1340
	}
1341 70e46e62 Ermal
1342 e5d558bf gnhb
	return NULL;
1343
}
1344
1345
function handle_pppoe_reset($post_array) {
1346
	global $config, $g;
1347
1348 70e46e62 Ermal
	$pppif = "{$post_array['type']}{$post_array['ptpid']}";
1349
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
1350 5c8e8a17 gnhb
1351 be45aa79 Renato Botelho
	if (!is_array($config['cron']['item']))
1352
		$config['cron']['item'] = array();
1353 70e46e62 Ermal
1354 1d7e1d6c gnhb
	$itemhash = getMPDCRONSettings($pppif);
1355 be45aa79 Renato Botelho
1356 e5d558bf gnhb
	// reset cron items if necessary and return
1357
	if (empty($post_array['pppoe-reset-type'])) {
1358 70e46e62 Ermal
		if (isset($itemhash))
1359 e5d558bf gnhb
			unset($config['cron']['item'][$itemhash['ID']]);
1360
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
1361
		return;
1362
	}
1363
1364 be45aa79 Renato Botelho
	if (empty($itemhash))
1365 70e46e62 Ermal
		$itemhash = array();
1366
	$item = array();
1367 e5d558bf gnhb
	if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "custom") {
1368
		$item['minute'] = $post_array['pppoe_resetminute'];
1369
		$item['hour'] = $post_array['pppoe_resethour'];
1370
		if (isset($post_array['pppoe_resetdate']) && $post_array['pppoe_resetdate'] <> "") {
1371
			$date = explode("/", $post_array['pppoe_resetdate']);
1372
			$item['mday'] = $date[1];
1373
			$item['month'] = $date[0];
1374
		} else {
1375
			$item['mday'] = "*";
1376
			$item['month'] = "*";
1377
		}
1378
		$item['wday'] = "*";
1379
		$item['who'] = "root";
1380 70e46e62 Ermal
		$item['command'] = $cron_cmd_file;
1381 e5d558bf gnhb
	} else if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "preset") {
1382
		switch ($post_array['pppoe_pr_preset_val']) {
1383 70e46e62 Ermal
		case "monthly":
1384
			$item['minute'] = "0";
1385
			$item['hour'] = "0";
1386
			$item['mday'] = "1";
1387
			$item['month'] = "*";
1388
			$item['wday'] = "*";
1389
			break;
1390 a8f5790a Renato Botelho
		case "weekly":
1391 70e46e62 Ermal
			$item['minute'] = "0";
1392
			$item['hour'] = "0";
1393
			$item['mday'] = "*";
1394
			$item['month'] = "*";
1395
			$item['wday'] = "0";
1396
			break;
1397
		case "daily":
1398
			$item['minute'] = "0";
1399
			$item['hour'] = "0";
1400
			$item['mday'] = "*";
1401
			$item['month'] = "*";
1402
			$item['wday'] = "*";
1403
			break;
1404
		case "hourly":
1405
			$item['minute'] = "0";
1406
			$item['hour'] = "*";
1407
			$item['mday'] = "*";
1408
			$item['month'] = "*";
1409
			$item['wday'] = "*";
1410
			break;
1411 e5d558bf gnhb
		} // end switch
1412 70e46e62 Ermal
		$item['who'] = "root";
1413
		$item['command'] = $cron_cmd_file;
1414
	}
1415
	if (empty($item))
1416
		return;
1417 be45aa79 Renato Botelho
	if (isset($item['ID']))
1418 70e46e62 Ermal
		$config['cron']['item'][$item['ID']] = $item;
1419 be45aa79 Renato Botelho
	else
1420 e5d558bf gnhb
		$config['cron']['item'][] = $item;
1421
}
1422
1423 70e46e62 Ermal
/*
1424
 * This function can configure PPPoE, MLPPP (PPPoE), PPTP.
1425
 * It writes the mpd config file to /var/etc every time the link is opened.
1426
 */
1427 cb37d8fa gnhb
function interface_ppps_configure($interface) {
1428
	global $config, $g;
1429 01c201e3 Ermal
1430
	/* Return for unassigned interfaces. This is a minimum requirement. */
1431
	if (empty($config['interfaces'][$interface]))
1432
		return 0;
1433
	$ifcfg = $config['interfaces'][$interface];
1434
	if (!isset($ifcfg['enable']))
1435
		return 0;
1436
1437 3a906378 gnhb
	// mpd5 requires a /var/spool/lock directory for PPP modem links.
1438
	if(!is_dir("/var/spool/lock")) {
1439
		exec("/bin/mkdir -p /var/spool/lock");
1440
		exec("/bin/chmod a+rw /var/spool/lock/.");
1441
	}
1442 7e631290 smos
	// mpd5 modem chat script expected in the same directory as the mpd_xxx.conf files
1443 3a906378 gnhb
	if (!file_exists("{$g['varetc_path']}/mpd.script"))
1444
		mwexec("/bin/ln -s /usr/local/sbin/mpd.script {$g['varetc_path']}/.");
1445 01c201e3 Ermal
1446 cb37d8fa gnhb
	if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1447
		foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1448 f7480829 gnhb
			if ($ifcfg['if'] == $ppp['if'])
1449 cb37d8fa gnhb
				break;
1450
		}
1451
	}
1452 f7480829 gnhb
	if (!$ppp || $ifcfg['if'] != $ppp['if']){
1453 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("Can't find PPP config for %s in interface_ppps_configure()."), $ifcfg['if']));
1454 3a906378 gnhb
		return 0;
1455 cb37d8fa gnhb
	}
1456 3a906378 gnhb
	$pppif = $ifcfg['if'];
1457 cb37d8fa gnhb
	if ($ppp['type'] == "ppp")
1458
		$type = "modem";
1459
	else
1460
		$type = $ppp['type'];
1461 be45aa79 Renato Botelho
	$upper_type = strtoupper($ppp['type']);
1462 01c201e3 Ermal
1463 3a906378 gnhb
	if($g['booting']) {
1464 bfbb9bc0 Ermal
		$descr = isset($ifcfg['descr']) ? $ifcfg['descr'] : strtoupper($interface);
1465 3a90c973 gnhb
		echo "starting {$pppif} link...";
1466 3a906378 gnhb
		// Do not re-configure the interface if we are booting and it's already been started
1467
		if(file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid"))
1468
			return 0;
1469
	}
1470 01c201e3 Ermal
1471 3a906378 gnhb
	$ports = explode(',',$ppp['ports']);
1472 bfbb9bc0 Ermal
	if ($type != "modem") {
1473 8e9d1265 Renato Botelho
		foreach ($ports as $pid => $port) {
1474 bfbb9bc0 Ermal
			$ports[$pid] = get_real_interface($port);
1475 8e9d1265 Renato Botelho
			if (empty($ports[$pid]))
1476
				return 0;
1477
		}
1478 bfbb9bc0 Ermal
	}
1479 3a906378 gnhb
	$localips = explode(',',$ppp['localip']);
1480
	$gateways = explode(',',$ppp['gateway']);
1481
	$subnets = explode(',',$ppp['subnet']);
1482 01c201e3 Ermal
1483 3a906378 gnhb
	/* We bring up the parent interface first because if DHCP is configured on the parent we need
1484 01c201e3 Ermal
	 * to obtain an address first so we can write it in the mpd .conf file for PPTP and L2TP configs
1485
	 */
1486 3a906378 gnhb
	foreach($ports as $pid => $port){
1487 23721285 gnhb
		switch ($ppp['type']) {
1488 be45aa79 Renato Botelho
			case "pppoe":
1489 3a906378 gnhb
				/* Bring the parent interface up */
1490
				interfaces_bring_up($port);
1491 3d04de61 Ermal
				pfSense_ngctl_attach(".", $port);
1492 84086442 Renato Botelho
				/* Enable setautosrc to automatically change mac address if parent interface's changes */
1493
				mwexec("ngctl msg {$port}: setautosrc 1");
1494 3a906378 gnhb
				break;
1495
			case "pptp":
1496
			case "l2tp":
1497
				/* configure interface */
1498 69c1b043 gnhb
				if(is_ipaddr($localips[$pid])){
1499 3a906378 gnhb
					// Manually configure interface IP/subnet
1500 bfbb9bc0 Ermal
					pfSense_interface_setaddress($port, "{$localips[$pid]}/{$subnets[$pid]}");
1501
					interfaces_bring_up($port);
1502 69c1b043 gnhb
				} else if (empty($localips[$pid]))
1503
					$localips[$pid] = get_interface_ip($port); // try to get the interface IP from the port
1504 be45aa79 Renato Botelho
1505 69c1b043 gnhb
				if(!is_ipaddr($localips[$pid])){
1506 d421e319 Ermal
					log_error("Could not get a Local IP address for PPTP/L2TP link on {$port} in interfaces_ppps_configure. Using 0.0.0.0 ip!");
1507
					$localips[$pid] = "0.0.0.0";
1508 3a906378 gnhb
				}
1509 69c1b043 gnhb
				if(!is_ipaddr($gateways[$pid])){
1510 addc0439 Renato Botelho
					log_error(sprintf(gettext('Could not get a PPTP/L2TP Remote IP address from %1$s for %2$s in interfaces_ppps_configure.'), $dhcp_gateway, $gway));
1511 69c1b043 gnhb
					return 0;
1512 3a906378 gnhb
				}
1513 3d04de61 Ermal
				pfSense_ngctl_attach(".", $port);
1514 3a906378 gnhb
				break;
1515
			case "ppp":
1516
				if (!file_exists("{$port}")) {
1517 07e40c1f Carlos Eduardo Ramos
					log_error(sprintf(gettext("Device %s does not exist. PPP link cannot start without the modem device."), $port));
1518 23721285 gnhb
					return 0;
1519 3a906378 gnhb
				}
1520
				break;
1521
			default:
1522 07e40c1f Carlos Eduardo Ramos
				log_error(sprintf(gettext("Unkown %s configured as ppp interface."), $type));
1523 3a906378 gnhb
				break;
1524
		}
1525
	}
1526 be45aa79 Renato Botelho
1527 cb37d8fa gnhb
	if (is_array($ports) && count($ports) > 1)
1528
		$multilink = "enable";
1529
	else
1530
		$multilink = "disable";
1531 be45aa79 Renato Botelho
1532 cb37d8fa gnhb
	if ($type == "modem"){
1533
		if (is_ipaddr($ppp['localip']))
1534
			$localip = $ppp['localip'];
1535
		else
1536
			$localip = '0.0.0.0';
1537
1538
		if (is_ipaddr($ppp['gateway']))
1539
			$gateway = $ppp['gateway'];
1540
		else
1541 23721285 gnhb
			$gateway = "10.64.64.{$pppid}";
1542 cb37d8fa gnhb
		$ranges = "{$localip}/0 {$gateway}/0";
1543 be45aa79 Renato Botelho
1544
		if (empty($ppp['apnum']))
1545 3a906378 gnhb
			$ppp['apnum'] = 1;
1546 23721285 gnhb
	} else
1547 cb37d8fa gnhb
		$ranges = "0.0.0.0/0 0.0.0.0/0";
1548 0661b194 gnhb
1549 be45aa79 Renato Botelho
	if (isset($ppp['ondemand']))
1550 cb37d8fa gnhb
		$ondemand = "enable";
1551
	else
1552
		$ondemand = "disable";
1553
	if (!isset($ppp['idletimeout']))
1554
		$ppp['idletimeout'] = 0;
1555 64d124c5 gnhb
1556 cb37d8fa gnhb
	if (empty($ppp['username']) && $type == "modem"){
1557
		$ppp['username'] = "user";
1558
		$ppp['password'] = "none";
1559
	}
1560
	if (empty($ppp['password']) && $type == "modem")
1561 00b702cc gnhb
		$passwd = "none";
1562
	else
1563
		$passwd = base64_decode($ppp['password']);
1564 0661b194 gnhb
1565
	$bandwidths = explode(',',$ppp['bandwidth']);
1566 6805d2d2 Ermal
	$defaultmtu = "1492";
1567
	if (!empty($ifcfg['mtu']))
1568
		$defaultmtu = intval($ifcfg['mtu']);
1569 0661b194 gnhb
	$mtus = explode(',',$ppp['mtu']);
1570
	$mrus = explode(',',$ppp['mru']);
1571
1572 c1cc447c gnhb
	if (isset($ppp['mrru']))
1573 0661b194 gnhb
		$mrrus = explode(',',$ppp['mrru']);
1574 c1cc447c gnhb
1575 cb37d8fa gnhb
	// Construct the mpd.conf file
1576
	$mpdconf = <<<EOD
1577
startup:
1578
	# configure the console
1579
	set console close
1580
	# configure the web server
1581
	set web close
1582
1583
default:
1584
{$ppp['type']}client:
1585
	create bundle static {$interface}
1586 07dfd121 Seth Mos
	set bundle enable ipv6cp
1587 cb37d8fa gnhb
	set iface name {$pppif}
1588
1589
EOD;
1590 0661b194 gnhb
	$setdefaultgw = false;
1591
	$founddefaultgw = false;
1592
	if (is_array($config['gateways']['gateway_item'])) {
1593
		foreach($config['gateways']['gateway_item'] as $gateway) {
1594
			if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
1595
				$setdefaultgw = true;
1596
				break;
1597
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
1598
				$founddefaultgw = true;
1599
				break;
1600
			}
1601
		}
1602
	}
1603 be45aa79 Renato Botelho
1604 82effddb gnhb
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true){
1605
		$setdefaultgw = true;
1606 cb37d8fa gnhb
		$mpdconf .= <<<EOD
1607
	set iface route default
1608
1609
EOD;
1610 82effddb gnhb
	}
1611 cb37d8fa gnhb
	$mpdconf .= <<<EOD
1612
	set iface {$ondemand} on-demand
1613
	set iface idle {$ppp['idletimeout']}
1614
1615
EOD;
1616
1617 0661b194 gnhb
	if (isset($ppp['ondemand']))
1618 cb37d8fa gnhb
		$mpdconf .= <<<EOD
1619 55f3ca1d gnhb
	set iface addrs 10.10.1.1 10.10.1.2
1620 cb37d8fa gnhb
1621
EOD;
1622 be45aa79 Renato Botelho
1623 0661b194 gnhb
	if (isset($ppp['tcpmssfix']))
1624 8adc1e49 gnhb
		$tcpmss = "disable";
1625
	else
1626
		$tcpmss = "enable";
1627 64d124c5 gnhb
		$mpdconf .= <<<EOD
1628 8adc1e49 gnhb
	set iface {$tcpmss} tcpmssfix
1629 64d124c5 gnhb
1630
EOD;
1631 0661b194 gnhb
1632 cb37d8fa gnhb
	$mpdconf .= <<<EOD
1633
	set iface up-script /usr/local/sbin/ppp-linkup
1634
	set iface down-script /usr/local/sbin/ppp-linkdown
1635
	set ipcp ranges {$ranges}
1636
1637
EOD;
1638 0661b194 gnhb
	if (isset($ppp['vjcomp']))
1639 cb37d8fa gnhb
		$mpdconf .= <<<EOD
1640 64d124c5 gnhb
	set ipcp no vjcomp
1641 cb37d8fa gnhb
1642
EOD;
1643
1644 bfbb9bc0 Ermal
	if (isset($config['system']['dnsallowoverride']))
1645 64d124c5 gnhb
		$mpdconf .= <<<EOD
1646
	set ipcp enable req-pri-dns
1647
	set ipcp enable req-sec-dns
1648
1649
EOD;
1650 23721285 gnhb
	if (!isset($ppp['verbose_log']))
1651
		$mpdconf .= <<<EOD
1652 5d9d443a gnhb
	#log -bund -ccp -chat -iface -ipcp -lcp -link
1653 0661b194 gnhb
1654 23721285 gnhb
EOD;
1655 64d124c5 gnhb
	foreach($ports as $pid => $port){
1656 bfbb9bc0 Ermal
		$port = get_real_interface($port);
1657 00b702cc gnhb
		$mpdconf .= <<<EOD
1658 cb37d8fa gnhb
1659 0661b194 gnhb
	create link static {$interface}_link{$pid} {$type}
1660 cb37d8fa gnhb
	set link action bundle {$interface}
1661
	set link {$multilink} multilink
1662
	set link keep-alive 10 60
1663
	set link max-redial 0
1664 64d124c5 gnhb
1665
EOD;
1666 0661b194 gnhb
		if (isset($ppp['shortseq']))
1667 00b702cc gnhb
			$mpdconf .= <<<EOD
1668 64d124c5 gnhb
	set link no shortseq
1669
1670
EOD;
1671 0661b194 gnhb
1672
		if (isset($ppp['acfcomp']))
1673 00b702cc gnhb
			$mpdconf .= <<<EOD
1674 64d124c5 gnhb
	set link no acfcomp
1675
1676
EOD;
1677 0661b194 gnhb
1678
		if (isset($ppp['protocomp']))
1679 00b702cc gnhb
			$mpdconf .= <<<EOD
1680 64d124c5 gnhb
	set link no protocomp
1681
1682
EOD;
1683 0661b194 gnhb
1684 00b702cc gnhb
		$mpdconf .= <<<EOD
1685 cb37d8fa gnhb
	set link disable chap pap
1686
	set link accept chap pap eap
1687 64d124c5 gnhb
	set link disable incoming
1688 cb37d8fa gnhb
1689
EOD;
1690 00b702cc gnhb
1691
1692 0661b194 gnhb
		if (!empty($bandwidths[$pid]))
1693 00b702cc gnhb
			$mpdconf .= <<<EOD
1694
	set link bandwidth {$bandwidths[$pid]}
1695 cb37d8fa gnhb
1696
EOD;
1697 0661b194 gnhb
1698 8adc1e49 gnhb
		if (empty($mtus[$pid]))
1699 6805d2d2 Ermal
			$mtus[$pid] = $defaultmtu;
1700 00b702cc gnhb
			$mpdconf .= <<<EOD
1701
	set link mtu {$mtus[$pid]}
1702 cb37d8fa gnhb
1703
EOD;
1704 0661b194 gnhb
1705
		if (!empty($mrus[$pid]))
1706 00b702cc gnhb
			$mpdconf .= <<<EOD
1707
	set link mru {$mrus[$pid]}
1708
1709 6a30f701 gnhb
EOD;
1710
1711
		if (!empty($mrrus[$pid]))
1712
			$mpdconf .= <<<EOD
1713
	set link mrru {$mrrus[$pid]}
1714
1715 00b702cc gnhb
EOD;
1716 0661b194 gnhb
1717 00b702cc gnhb
		$mpdconf .= <<<EOD
1718 cb37d8fa gnhb
	set auth authname "{$ppp['username']}"
1719
	set auth password {$passwd}
1720
1721
EOD;
1722 00b702cc gnhb
		if ($type == "modem") {
1723
			$mpdconf .= <<<EOD
1724 cb37d8fa gnhb
	set modem device {$ppp['ports']}
1725
	set modem script DialPeer
1726 73472985 Ermal
	set modem idle-script Ringback
1727 cb37d8fa gnhb
	set modem watch -cd
1728
	set modem var \$DialPrefix "DT"
1729
	set modem var \$Telephone "{$ppp['phone']}"
1730
1731
EOD;
1732 00b702cc gnhb
		}
1733
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1734
			$mpdconf .= <<<EOD
1735 cb37d8fa gnhb
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1736
1737
EOD;
1738 00b702cc gnhb
		}
1739
		if (isset($ppp['initstr']) && $type == "modem") {
1740
			$initstr = base64_decode($ppp['initstr']);
1741
			$mpdconf .= <<<EOD
1742 cb37d8fa gnhb
	set modem var \$InitString "{$initstr}"
1743
1744
EOD;
1745 00b702cc gnhb
		}
1746
		if (isset($ppp['simpin']) && $type == "modem") {
1747 03f7925a jim-p
			if($ppp['pin-wait'] == "")
1748 2a210730 smos
				$ppp['pin-wait'] = 0;
1749 00b702cc gnhb
			$mpdconf .= <<<EOD
1750 cb37d8fa gnhb
	set modem var \$SimPin "{$ppp['simpin']}"
1751
	set modem var \$PinWait "{$ppp['pin-wait']}"
1752
1753
EOD;
1754 00b702cc gnhb
		}
1755
		if (isset($ppp['apn']) && $type == "modem") {
1756
			$mpdconf .= <<<EOD
1757 cb37d8fa gnhb
	set modem var \$APN "{$ppp['apn']}"
1758
	set modem var \$APNum "{$ppp['apnum']}"
1759
1760
EOD;
1761 00b702cc gnhb
		}
1762 233e2af1 jim-p
		if ($type == "pppoe") {
1763
			// Send a null service name if none is set.
1764
			$provider = isset($ppp['provider']) ? $ppp['provider'] : "";
1765 00b702cc gnhb
			$mpdconf .= <<<EOD
1766 233e2af1 jim-p
	set pppoe service "{$provider}"
1767 cb37d8fa gnhb
1768
EOD;
1769 00b702cc gnhb
		}
1770 0661b194 gnhb
		if ($type == "pppoe")
1771 00b702cc gnhb
			$mpdconf .= <<<EOD
1772 64d124c5 gnhb
	set pppoe iface {$port}
1773 cb37d8fa gnhb
1774
EOD;
1775 0661b194 gnhb
1776 39f750b5 gnhb
		if ($type == "pptp" || $type == "l2tp") {
1777 00b702cc gnhb
			$mpdconf .= <<<EOD
1778 18ec0f13 Ermal
	set {$type} self {$localips[$pid]}
1779
	set {$type} peer {$gateways[$pid]}
1780 cb37d8fa gnhb
1781
EOD;
1782 00b702cc gnhb
		}
1783 be45aa79 Renato Botelho
1784 04f357bc Ermal
		$mpdconf .= "\topen\n";
1785 cb37d8fa gnhb
	} //end foreach($port)
1786
1787 df309b37 gnhb
1788
	/* Generate mpd.conf. If mpd_[interface].conf exists in the conf path, then link to it instead of generating a fresh conf file. */
1789
	if (file_exists("{$g['conf_path']}/mpd_{$interface}.conf"))
1790
		mwexec("/bin/ln -s {$g['conf_path']}/mpd_{$interface}.conf {$g['varetc_path']}/.");
1791
	else {
1792
		$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1793
		if (!$fd) {
1794 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Error: cannot open mpd_%s.conf in interface_ppps_configure().%s"), $interface, "\n"));
1795 df309b37 gnhb
			return 0;
1796
		}
1797
		// Write out mpd_ppp.conf
1798
		fwrite($fd, $mpdconf);
1799
		fclose($fd);
1800 14d079b3 Ermal
		unset($mpdconf);
1801 df309b37 gnhb
	}
1802 cb37d8fa gnhb
1803
	// Create the uptime log if requested and if it doesn't exist already, or delete it if it is no longer requested.
1804
	if (isset($ppp['uptime'])) {
1805
		if (!file_exists("/conf/{$pppif}.log")) {
1806
			conf_mount_rw();
1807
			mwexec("echo /dev/null > /conf/{$pppif}.log");
1808
			conf_mount_ro();
1809
		}
1810
	} else {
1811
		if (file_exists("/conf/{$pppif}.log")) {
1812
			conf_mount_rw();
1813
			mwexec("rm -f /conf/{$pppif}.log");
1814
			conf_mount_ro();
1815
		}
1816
	}
1817 92a1c8e6 Ermal
1818 7e631290 smos
	/* clean up old lock files */
1819
	foreach($ports as $port) {
1820 17d656fc smos
		if(file_exists("{$g['var_path']}/spool/lock/LCK..{$port}"))
1821
			unlink("{$g['var_path']}/spool/lock/LCK..{$port}");
1822 7e631290 smos
	}
1823
1824 3a906378 gnhb
	/* fire up mpd */
1825
	mwexec("/usr/local/sbin/mpd5 -b -k -d {$g['varetc_path']} -f mpd_{$interface}.conf -p {$g['varrun_path']}/{$ppp['type']}_{$interface}.pid -s ppp {$ppp['type']}client");
1826
1827 be45aa79 Renato Botelho
	// Check for PPPoE periodic reset request
1828 bfbb9bc0 Ermal
	if ($type == "pppoe") {
1829 70e46e62 Ermal
		if (!empty($ppp['pppoe-reset-type']))
1830
			interface_setup_pppoe_reset_file($ppp['if'], $interface);
1831 766bd6d0 gnhb
		else
1832 70e46e62 Ermal
			interface_setup_pppoe_reset_file($ppp['if']);
1833 cb37d8fa gnhb
	}
1834 302d646e smos
	/* wait for upto 10 seconds for the interface to appear (ppp(oe)) */
1835
	$i = 0;
1836
	while($i < 10) {
1837
		exec("/sbin/ifconfig {$ppp['if']} 2>&1", $out, $ret);
1838
		if($ret == 0)
1839
			break;
1840
		sleep(1);
1841
		$i++;
1842
	}
1843 cb37d8fa gnhb
1844 117f8e6f smos
	/* we only support the 3gstats.php for huawei modems for now. Will add more later. */
1845
	/* We should be able to launch the right version for each modem */
1846
	/* We can also guess the mondev from the manufacturer */
1847
	exec("usbconfig | egrep -ie '(huawei)'", $usbmodemoutput);
1848
	mwexec("/bin/ps auxww|grep \"{$interface}\" |grep \"[3]gstats\" | awk '{print $2}' |xargs kill");
1849 284101d3 smos
	foreach($ports as $port) {
1850 7056e4ed smos
		if(preg_match("/huawei/i", implode("\n", $usbmodemoutput))) {
1851 117f8e6f smos
			$mondev  = substr(basename($port), 0, -1);
1852
			$devlist = glob("/dev/{$mondev}?");
1853
			$mondev = basename(end($devlist));
1854 284101d3 smos
		}
1855 7056e4ed smos
		if(preg_match("/zte/i", implode("\n", $usbmodemoutput))) {
1856 284101d3 smos
			$mondev  = substr(basename($port), 0, -1) . "1";
1857
		}
1858
		log_error("Starting 3gstats.php on device '{$mondev}' for interface '{$interface}'");
1859
		mwexec_bg("/usr/local/bin/3gstats.php {$mondev} {$interface}");
1860 5e589685 smos
	}
1861
1862 23721285 gnhb
	return 1;
1863 cb37d8fa gnhb
}
1864
1865 abcb2bed Ermal Lu?i
function interfaces_carp_setup() {
1866 87a2efd1 Ermal Luçi
	global $g, $config;
1867 abcb2bed Ermal Lu?i
1868 84b32407 Ermal
	if (isset($config['system']['developerspew'])) {
1869 b932ef16 Scott Ullrich
		$mt = microtime();
1870 abcb2bed Ermal Lu?i
		echo "interfaces_carp_setup() being called $mt\n";
1871 b932ef16 Scott Ullrich
	}
1872 abcb2bed Ermal Lu?i
1873 b932ef16 Scott Ullrich
	if ($g['booting']) {
1874 07e40c1f Carlos Eduardo Ramos
		echo gettext("Configuring CARP settings...");
1875 7d0f4544 Scott Ullrich
		mute_kernel_msgs();
1876 a5250ebc Scott Ullrich
	}
1877 abcb2bed Ermal Lu?i
1878 b932ef16 Scott Ullrich
	/* suck in configuration items */
1879 84b32407 Ermal
	if ($config['hasync']) {
1880 f97a5b04 Darren Embry
		$pfsyncenabled = $config['hasync']['pfsyncenabled'];
1881
		$balanacing = $config['hasync']['balancing'];
1882
		$pfsyncinterface = $config['hasync']['pfsyncinterface'];
1883
		$pfsyncpeerip = $config['hasync']['pfsyncpeerip'];
1884 b932ef16 Scott Ullrich
	} else {
1885
		unset($pfsyncinterface);
1886
		unset($balanacing);
1887
		unset($pfsyncenabled);
1888 6008210b Scott Ullrich
	}
1889 abcb2bed Ermal Lu?i
1890 84b32407 Ermal
	if ($balanacing) {
1891
		mwexec("/sbin/sysctl net.inet.carp.arpbalance=1", true);
1892
		mwexec("/sbin/sysctl net.inet.carp.preempt=0", true);
1893 abcb2bed Ermal Lu?i
	} else
1894 be45aa79 Renato Botelho
		mwexec("/sbin/sysctl net.inet.carp.preempt=1", true);
1895 abcb2bed Ermal Lu?i
1896 84b32407 Ermal
	mwexec("sbin/sysctl net.inet.carp.log=1", true);
1897 abcb2bed Ermal Lu?i
	if (!empty($pfsyncinterface))
1898
		$carp_sync_int = get_real_interface($pfsyncinterface);
1899 84b32407 Ermal
	else
1900
		unset($carp_sync_int);
1901 abcb2bed Ermal Lu?i
1902 b932ef16 Scott Ullrich
	/* setup pfsync interface */
1903 84b32407 Ermal
	if ($carp_sync_int and $pfsyncenabled) {
1904 abcb2bed Ermal Lu?i
		if (is_ipaddr($pfsyncpeerip))
1905 dc2e5552 Renato Botelho
			$syncpeer = "syncpeer {$pfsyncpeerip}";
1906 abcb2bed Ermal Lu?i
		else
1907 dc2e5552 Renato Botelho
			$syncpeer = "-syncpeer";
1908
1909
		mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} {$syncpeer} up", false);
1910 abcb2bed Ermal Lu?i
1911 84b32407 Ermal
		sleep(1);
1912 2eb9c02f Ermal
1913 84b32407 Ermal
		/* XXX: Handle an issue with pfsync(4) and carp(4). In a cluster carp will come up before pfsync(4) has updated and so will cause issues
1914
		 * for existing sessions.
1915
		 */
1916 b32329fc smos
		log_error("waiting for pfsync...");
1917 1be1a67a PiBa-NL
		$i = 0;
1918
		while (intval(trim(`/sbin/ifconfig pfsync0 | /usr/bin/grep 'syncok: 0' | /usr/bin/grep -v grep | /usr/bin/wc -l`)) == 0 && $i < 30) {
1919
			$i++;
1920
			sleep(1);
1921
		}
1922 b32329fc smos
		log_error("pfsync done in $i seconds.");
1923
		log_error("Configuring CARP settings finalize...");
1924 b32ea59d Renato Botelho
	} else {
1925 fb6a3e7a Renato Botelho
		mwexec("/sbin/ifconfig pfsync0 -syncdev -syncpeer down", false);
1926 6930e805 Ermal
	}
1927 abcb2bed Ermal Lu?i
1928
	if($config['virtualip']['vip'])
1929 be45aa79 Renato Botelho
		mwexec("/sbin/sysctl net.inet.carp.allow=1", true);
1930 abcb2bed Ermal Lu?i
	else
1931 be45aa79 Renato Botelho
		mwexec("/sbin/sysctl net.inet.carp.allow=0", true);
1932
1933 abcb2bed Ermal Lu?i
	if ($g['booting']) {
1934
		unmute_kernel_msgs();
1935 07e40c1f Carlos Eduardo Ramos
		echo gettext("done.") . "\n";
1936 abcb2bed Ermal Lu?i
	}
1937 67ee1ec5 Ermal Luçi
}
1938
1939 962fd685 Ermal
function interface_proxyarp_configure($interface = "") {
1940 9006e9f8 Scott Ullrich
	global $config, $g;
1941
	if(isset($config['system']['developerspew'])) {
1942
		$mt = microtime();
1943
		echo "interface_proxyarp_configure() being called $mt\n";
1944
	}
1945 67ee1ec5 Ermal Luçi
1946 9006e9f8 Scott Ullrich
	/* kill any running choparp */
1947 962fd685 Ermal
	if (empty($interface))
1948
		killbyname("choparp");
1949 7c73f504 Ermal
	else {
1950
		$vipif = get_real_interface($interface);
1951
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
1952
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
1953
	}
1954 1b58b513 Scott Ullrich
1955 7c73f504 Ermal
	$paa = array();
1956
	if (!empty($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1957 e5d43d93 Scott Ullrich
1958 9006e9f8 Scott Ullrich
		/* group by interface */
1959
		foreach ($config['virtualip']['vip'] as $vipent) {
1960
			if ($vipent['mode'] === "proxyarp") {
1961
				if ($vipent['interface'])
1962
					$proxyif = $vipent['interface'];
1963
				else
1964
					$proxyif = "wan";
1965 be45aa79 Renato Botelho
1966 7e96ca27 Ermal
				if (!empty($interface) && $interface != $proxyif)
1967
					continue;
1968 abcb2bed Ermal Lu?i
1969 7c73f504 Ermal
				if (!is_array($paa[$proxyif]))
1970 9006e9f8 Scott Ullrich
					$paa[$proxyif] = array();
1971 7b2d4769 Bill Marquette
1972 9006e9f8 Scott Ullrich
				$paa[$proxyif][] = $vipent;
1973
			}
1974 962fd685 Ermal
		}
1975 9006e9f8 Scott Ullrich
	}
1976 e5d43d93 Scott Ullrich
1977 962fd685 Ermal
	if (!empty($interface)) {
1978
		if (is_array($paa[$interface])) {
1979
			$paaifip = get_interface_ip($interface);
1980 1c3ddd9e Renato Botelho
			if (!is_ipaddr($paaifip))
1981
				return;
1982
			$args = get_real_interface($interface) . " auto";
1983
			foreach ($paa[$interface] as $paent) {
1984
				if (isset($paent['subnet']))
1985
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1986
				else if (isset($paent['range']))
1987
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1988
			}
1989
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1990 962fd685 Ermal
		}
1991 7c73f504 Ermal
	} else if (count($paa) > 0) {
1992
		foreach ($paa as $paif => $paents)  {
1993 9006e9f8 Scott Ullrich
			$paaifip = get_interface_ip($paif);
1994 f814d3a6 Ermal
			if (!is_ipaddr($paaifip))
1995 9006e9f8 Scott Ullrich
				continue;
1996
			$args = get_real_interface($paif) . " auto";
1997
			foreach ($paents as $paent) {
1998
				if (isset($paent['subnet']))
1999
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
2000
				else if (isset($paent['range']))
2001 962fd685 Ermal
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
2002 9006e9f8 Scott Ullrich
			}
2003
			mwexec_bg("/usr/local/sbin/choparp " . $args);
2004
		}
2005
	}
2006 9f6b1429 Scott Ullrich
}
2007
2008 b877d635 Ermal
function interface_ipalias_cleanup($interface, $inet = "inet4") {
2009
	global $g, $config;
2010
2011
	if (is_array($config['virtualip']['vip'])) {
2012
		foreach ($config['virtualip']['vip'] as $vip) {
2013
			if ($vip['mode'] == "ipalias" && $vip['interface'] == $interface) {
2014
				if ($inet == "inet6" && is_ipaddrv6($vip['subnet']))
2015
					interface_vip_bring_down($vip);
2016
				else if ($inet == "inet4" && is_ipaddrv4($vip['subnet']))
2017
					interface_vip_bring_down($vip);
2018
			}
2019
		}
2020
	}
2021
}
2022
2023 e5ac67ed Ermal Lu?i
function interfaces_vips_configure($interface = "") {
2024 87a2efd1 Ermal Luçi
	global $g, $config;
2025 a04de17f Chris Buechler
	if(isset($config['system']['developerspew'])) {
2026
		$mt = microtime();
2027 123f030c Chris Buechler
		echo "interfaces_vips_configure() being called $mt\n";
2028 a04de17f Chris Buechler
	}
2029 abcb2bed Ermal Lu?i
	$paa = array();
2030
	if(is_array($config['virtualip']['vip'])) {
2031
		$carp_setuped = false;
2032 e5ac67ed Ermal Lu?i
		$anyproxyarp = false;
2033 abcb2bed Ermal Lu?i
		foreach ($config['virtualip']['vip'] as $vip) {
2034
			switch ($vip['mode']) {
2035
			case "proxyarp":
2036 123f030c Chris Buechler
				/* nothing it is handled on interface_proxyarp_configure() */
2037 e5ac67ed Ermal Lu?i
				if ($interface <> "" && $vip['interface'] <> $interface)
2038
					continue;
2039
				$anyproxyarp = true;
2040 abcb2bed Ermal Lu?i
				break;
2041
			case "ipalias":
2042 e5ac67ed Ermal Lu?i
				if ($interface <> "" && $vip['interface'] <> $interface)
2043
					continue;
2044 3dacbd7c Renato Botelho
				interface_ipalias_configure($vip);
2045 abcb2bed Ermal Lu?i
				break;
2046
			case "carp":
2047 e5ac67ed Ermal Lu?i
				if ($interface <> "" && $vip['interface'] <> $interface)
2048
					continue;
2049 bce14123 Ermal
				if ($carp_setuped == false)
2050 abcb2bed Ermal Lu?i
					$carp_setuped = true;
2051
				interface_carp_configure($vip);
2052
				break;
2053 6a74c90e Scott Ullrich
			}
2054 a04de17f Chris Buechler
		}
2055 bce14123 Ermal
		if ($carp_setuped == true)
2056
			interfaces_carp_setup();
2057 e5ac67ed Ermal Lu?i
		if ($anyproxyarp == true)
2058
			interface_proxyarp_configure();
2059 abcb2bed Ermal Lu?i
	}
2060
}
2061
2062
function interface_ipalias_configure(&$vip) {
2063
	if ($vip['mode'] == "ipalias") {
2064
		$if = get_real_interface($vip['interface']);
2065 ce73b2c5 smos
		$af = "inet";
2066
		if(is_ipaddrv6($vip['subnet']))
2067
			$af = "inet6";
2068
		mwexec("/sbin/ifconfig " . escapeshellarg($if) ." {$af} ". escapeshellarg($vip['subnet']) ."/" . escapeshellarg($vip['subnet_bits']) . " alias");
2069 a04de17f Chris Buechler
	}
2070
}
2071
2072 abcb2bed Ermal Lu?i
function interface_reload_carps($cif) {
2073
	global $config;
2074
2075
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
2076 9006e9f8 Scott Ullrich
	if (empty($carpifs))
2077 abcb2bed Ermal Lu?i
		return;
2078
2079
	$carps = explode(" ", $carpifs);
2080
	if(is_array($config['virtualip']['vip'])) {
2081 9006e9f8 Scott Ullrich
		$viparr = &$config['virtualip']['vip'];
2082
		foreach ($viparr as $vip) {
2083 abcb2bed Ermal Lu?i
			if (in_array($vip['carpif'], $carps)) {
2084 9006e9f8 Scott Ullrich
				switch ($vip['mode']) {
2085 89830b60 Ermal
				case "carp":
2086 abcb2bed Ermal Lu?i
					interface_vip_bring_down($vip);
2087
					sleep(1);
2088 9006e9f8 Scott Ullrich
					interface_carp_configure($vip);
2089
					break;
2090 89830b60 Ermal
				case "ipalias":
2091
					interface_vip_bring_down($vip);
2092
					sleep(1);
2093
					interface_ipalias_configure($vip);
2094
					break;
2095 abcb2bed Ermal Lu?i
				}
2096 9006e9f8 Scott Ullrich
			}
2097
		}
2098
	}
2099 abcb2bed Ermal Lu?i
}
2100
2101
function interface_carp_configure(&$vip) {
2102
	global $config, $g;
2103
	if(isset($config['system']['developerspew'])) {
2104 58ebf6bb Scott Ullrich
		$mt = microtime();
2105 0a595d84 Ermal Lu?i
		echo "interface_carp_configure() being called $mt\n";
2106 58ebf6bb Scott Ullrich
	}
2107 abcb2bed Ermal Lu?i
2108
	if ($vip['mode'] != "carp")
2109
		return;
2110
2111
	/*
2112
	 * ensure the interface containing the VIP really exists
2113 1c3ddd9e Renato Botelho
	 * prevents a panic if the interface is missing or invalid
2114 58ebf6bb Scott Ullrich
	 */
2115
	$realif = get_real_interface($vip['interface']);
2116
	if (!does_interface_exist($realif)) {
2117 07e40c1f Carlos Eduardo Ramos
		file_notice("CARP", sprintf(gettext("Interface specified for the virtual IP address %s does not exist. Skipping this VIP."), $vip['subnet']), "Firewall: Virtual IP", "");
2118 58ebf6bb Scott Ullrich
		return;
2119
	}
2120 abcb2bed Ermal Lu?i
2121 3502b5b1 Seth Mos
	if(is_ipaddrv4($vip['subnet'])) {
2122
		/* Ensure CARP IP really exists prior to loading up. */
2123
		$ww_subnet_ip = find_interface_ip($realif);
2124
		$ww_subnet_bits = find_interface_subnet($realif);
2125
		if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) {
2126 8b6313a4 jim-p
			file_notice("CARP", sprintf(gettext("Sorry but we could not find a matching real interface subnet for the virtual IP address %s."), $vip['subnet']), "Firewall: Virtual IP", "");
2127 3502b5b1 Seth Mos
			return;
2128
		}
2129
	}
2130
	if(is_ipaddrv6($vip['subnet'])) {
2131
		/* Ensure CARP IP really exists prior to loading up. */
2132
		$ww_subnet_ip = find_interface_ipv6($realif);
2133
		$ww_subnet_bits = find_interface_subnetv6($realif);
2134
		if (!ip_in_subnet($vip['subnet'], gen_subnetv6($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) {
2135 8b6313a4 jim-p
			file_notice("CARP", sprintf(gettext("Sorry but we could not find a matching real interface subnet for the virtual IPv6 address %s."), $vip['subnet']), "Firewall: Virtual IP", "");
2136 3502b5b1 Seth Mos
			return;
2137
		}
2138 f99aa333 Ermal
	}
2139
2140 7b47bd4c Ermal
	// set the vip interface to the vhid
2141
	$vipif = "{$vip['interface']}_vip{$vip['vhid']}";
2142 abcb2bed Ermal Lu?i
2143
	/* create the carp interface and setup */
2144 37a53d16 Scott Ullrich
	if (does_interface_exist($vipif)) {
2145 871768cf Ermal
		pfSense_interface_flags($vipif, -IFF_UP);
2146 37a53d16 Scott Ullrich
	} else {
2147 871768cf Ermal
		$carpif = pfSense_interface_create("carp");
2148
		pfSense_interface_rename($carpif, $vipif);
2149
		pfSense_ngctl_name("{$carpif}:", $vipif);
2150 abcb2bed Ermal Lu?i
	}
2151
2152
	/* invalidate interface cache */
2153
	get_interface_arr(true);
2154
2155 7b47bd4c Ermal
	$vip_password = $vip['password'];
2156
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
2157
	if ($vip['password'] != "")
2158
		$password = " pass {$vip_password}";
2159 a687f866 Namezero
2160 7b47bd4c Ermal
	$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
2161 100b7219 Ermal
	$advbase = "";
2162
	if (!empty($vip['advbase']))
2163
		$advbase = "advbase {$vip['advbase']}";
2164 1f74cd2d Seth Mos
2165 3502b5b1 Seth Mos
	if(is_ipaddrv4($vip['subnet'])) {
2166
		$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
2167 9caffe86 Seth Mos
		mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}");
2168 3502b5b1 Seth Mos
	}
2169
	if(is_ipaddrv6($vip['subnet'])) {
2170
		$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
2171 9caffe86 Seth Mos
		mwexec("/sbin/ifconfig {$vipif} inet6 {$vip['subnet']} prefixlen {$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}");
2172 3502b5b1 Seth Mos
	}
2173 abcb2bed Ermal Lu?i
2174
	interfaces_bring_up($vipif);
2175 7b47bd4c Ermal
2176 abcb2bed Ermal Lu?i
	return $vipif;
2177
}
2178
2179 854aed18 Ermal Lu?i
function interface_wireless_clone($realif, $wlcfg) {
2180 568b1358 Scott Ullrich
	global $config, $g;
2181 be45aa79 Renato Botelho
	/*   Check to see if interface has been cloned as of yet.
2182 88157f66 Scott Ullrich
	 *   If it has not been cloned then go ahead and clone it.
2183
	 */
2184 2a203afd Seth Mos
	$needs_clone = false;
2185 9f428275 Erik Fonnesbeck
	if(is_array($wlcfg['wireless']))
2186
		$wlcfg_mode = $wlcfg['wireless']['mode'];
2187
	else
2188
		$wlcfg_mode = $wlcfg['mode'];
2189
	switch($wlcfg_mode) {
2190 a8f5790a Renato Botelho
	case "hostap":
2191
		$mode = "wlanmode hostap";
2192
		break;
2193
	case "adhoc":
2194
		$mode = "wlanmode adhoc";
2195
		break;
2196
	default:
2197
		$mode = "";
2198
		break;
2199 2a203afd Seth Mos
	}
2200 34808d4e Erik Fonnesbeck
	$baseif = interface_get_wireless_base($wlcfg['if']);
2201 854aed18 Ermal Lu?i
	if(does_interface_exist($realif)) {
2202
		exec("/sbin/ifconfig {$realif}", $output, $ret);
2203 2a203afd Seth Mos
		$ifconfig_str = implode($output);
2204 9f428275 Erik Fonnesbeck
		if(($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
2205 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Interface %s changed to hostap mode"), $realif));
2206 2a203afd Seth Mos
			$needs_clone = true;
2207
		}
2208 9f428275 Erik Fonnesbeck
		if(($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
2209 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Interface %s changed to adhoc mode"), $realif));
2210 2a203afd Seth Mos
			$needs_clone = true;
2211
		}
2212 9f428275 Erik Fonnesbeck
		if(($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
2213 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Interface %s changed to infrastructure mode"), $realif));
2214 2a203afd Seth Mos
			$needs_clone = true;
2215
		}
2216
	} else {
2217
		$needs_clone = true;
2218 88157f66 Scott Ullrich
	}
2219 2a203afd Seth Mos
2220 19e83210 Scott Ullrich
	if($needs_clone == true) {
2221 2a203afd Seth Mos
		/* remove previous instance if it exists */
2222 854aed18 Ermal Lu?i
		if(does_interface_exist($realif))
2223 871768cf Ermal
			pfSense_interface_destroy($realif);
2224 854aed18 Ermal Lu?i
2225 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("Cloning new wireless interface %s"), $realif));
2226 b99256c1 Scott Ullrich
		// Create the new wlan interface. FreeBSD returns the new interface name.
2227
		// example:  wlan2
2228 6d54e865 Erik Fonnesbeck
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
2229 2a203afd Seth Mos
		if($ret <> 0) {
2230 addc0439 Renato Botelho
			log_error(sprintf(gettext('Failed to clone interface %1$s with error code %2$s, output %3$s'), $baseif, $ret, $out[0]));
2231 9f428275 Erik Fonnesbeck
			return false;
2232 2a203afd Seth Mos
		}
2233
		$newif = trim($out[0]);
2234
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
2235 871768cf Ermal
		pfSense_interface_rename($newif, $realif);
2236 2a203afd Seth Mos
		// FIXME: not sure what ngctl is for. Doesn't work.
2237 fa71a9b6 Erik Fonnesbeck
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
2238 acb0bce0 Erik Fonnesbeck
		file_put_contents("{$g['tmp_path']}/{$realif}_oldmac", get_interface_mac($realif));
2239 88157f66 Scott Ullrich
	}
2240 9f428275 Erik Fonnesbeck
	return true;
2241 88157f66 Scott Ullrich
}
2242
2243 8f0289e7 Erik Fonnesbeck
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
2244
	global $config, $g;
2245
2246 56626335 Erik Fonnesbeck
	$shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel',
2247 a8f5790a Renato Botelho
				 'diversity', 'txantenna', 'rxantenna', 'distance',
2248
				 'regdomain', 'regcountry', 'reglocation');
2249 8f0289e7 Erik Fonnesbeck
2250 263e2b7e Erik Fonnesbeck
	if(!is_interface_wireless($ifcfg['if']))
2251 7de319a1 Erik Fonnesbeck
		return;
2252
2253 34808d4e Erik Fonnesbeck
	$baseif = interface_get_wireless_base($ifcfg['if']);
2254 8f0289e7 Erik Fonnesbeck
2255 062023a5 Erik Fonnesbeck
	// Sync shared settings for assigned clones
2256 38b7d47d Erik Fonnesbeck
	$iflist = get_configured_interface_list(false, true);
2257 8f0289e7 Erik Fonnesbeck
	foreach ($iflist as $if) {
2258 34808d4e Erik Fonnesbeck
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
2259 8f0289e7 Erik Fonnesbeck
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
2260
				foreach ($shared_settings as $setting) {
2261
					if ($sync_changes) {
2262 56626335 Erik Fonnesbeck
						if (isset($ifcfg['wireless'][$setting]))
2263
							$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
2264
						else if (isset($config['interfaces'][$if]['wireless'][$setting]))
2265
							unset($config['interfaces'][$if]['wireless'][$setting]);
2266 8f0289e7 Erik Fonnesbeck
					} else {
2267 56626335 Erik Fonnesbeck
						if (isset($config['interfaces'][$if]['wireless'][$setting]))
2268
							$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
2269
						else if (isset($ifcfg['wireless'][$setting]))
2270
							unset($ifcfg['wireless'][$setting]);
2271 8f0289e7 Erik Fonnesbeck
					}
2272
				}
2273
				if (!$sync_changes)
2274
					break;
2275
			}
2276
		}
2277
	}
2278 263e2b7e Erik Fonnesbeck
2279 062023a5 Erik Fonnesbeck
	// Read or write settings at shared area
2280 6ef2297b Erik Fonnesbeck
	if (isset($config['wireless']['interfaces'][$baseif]) && is_array($config['wireless']['interfaces'][$baseif])) {
2281 f62c44d8 Erik Fonnesbeck
		foreach ($shared_settings as $setting) {
2282
			if ($sync_changes) {
2283 56626335 Erik Fonnesbeck
				if (isset($ifcfg['wireless'][$setting]))
2284
					$config['wireless']['interfaces'][$baseif][$setting] = $ifcfg['wireless'][$setting];
2285
				else if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2286
					unset($config['wireless']['interfaces'][$baseif][$setting]);
2287 f62c44d8 Erik Fonnesbeck
			} else if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
2288 56626335 Erik Fonnesbeck
				if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2289
					$ifcfg['wireless'][$setting] = $config['wireless']['interfaces'][$baseif][$setting];
2290
				else if (isset($ifcfg['wireless'][$setting]))
2291
					unset($ifcfg['wireless'][$setting]);
2292 f62c44d8 Erik Fonnesbeck
			}
2293 062023a5 Erik Fonnesbeck
		}
2294
	}
2295
2296
	// Sync the mode on the clone creation page with the configured mode on the interface
2297 6ef2297b Erik Fonnesbeck
	if (interface_is_wireless_clone($ifcfg['if']) && isset($config['wireless']['clone']) && is_array($config['wireless']['clone'])) {
2298 263e2b7e Erik Fonnesbeck
		foreach ($config['wireless']['clone'] as &$clone) {
2299
			if ($clone['cloneif'] == $ifcfg['if']) {
2300
				if ($sync_changes) {
2301
					$clone['mode'] = $ifcfg['wireless']['mode'];
2302
				} else {
2303
					$ifcfg['wireless']['mode'] = $clone['mode'];
2304
				}
2305
				break;
2306
			}
2307
		}
2308 867d444b Erik Fonnesbeck
		unset($clone);
2309 263e2b7e Erik Fonnesbeck
	}
2310 8f0289e7 Erik Fonnesbeck
}
2311
2312 19e83210 Scott Ullrich
function interface_wireless_configure($if, &$wl, &$wlcfg) {
2313 ac3f8318 Espen Johansen
	global $config, $g;
2314 eb772abd Scott Ullrich
2315 4742e927 Scott Ullrich
	/*    open up a shell script that will be used to output the commands.
2316
	 *    since wireless is changing a lot, these series of commands are fragile
2317 905ea336 Phil Davis
	 *    and will sometimes need to be verified by a operator by executing the command
2318
	 *    and returning the output of the command to the developers for inspection.  please
2319
	 *    do not change this routine from a shell script to individual exec commands.  -sullrich
2320 4742e927 Scott Ullrich
	 */
2321 eb772abd Scott Ullrich
2322 b99256c1 Scott Ullrich
	// Remove script file
2323 490b8b2a Scott Ullrich
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
2324 eb772abd Scott Ullrich
2325 0a28d385 Erik Fonnesbeck
	// Clone wireless nic if needed.
2326
	interface_wireless_clone($if, $wl);
2327
2328 8f0289e7 Erik Fonnesbeck
	// Reject inadvertent changes to shared settings in case the interface hasn't been configured.
2329
	interface_sync_wireless_clones($wl, false);
2330
2331 6955830f Ermal Lu?i
	$fd_set = fopen("{$g['tmp_path']}/{$if}_setup.sh","w");
2332 4742e927 Scott Ullrich
	fwrite($fd_set, "#!/bin/sh\n");
2333 36d0358b Scott Ullrich
	fwrite($fd_set, "# {$g['product_name']} wireless configuration script.\n\n");
2334 eb772abd Scott Ullrich
2335 2ac908dd Espen Johansen
	/* set values for /path/program */
2336
	$hostapd = "/usr/sbin/hostapd";
2337
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
2338 4742e927 Scott Ullrich
	$ifconfig = "/sbin/ifconfig";
2339 56626335 Erik Fonnesbeck
	$sysctl = "/sbin/sysctl";
2340 4742e927 Scott Ullrich
	$killall = "/usr/bin/killall";
2341 2ac908dd Espen Johansen
2342 905ea336 Phil Davis
	/* Set all wireless ifconfig variables (split up to get rid of needed checking) */
2343 5508cf57 Scott Ullrich
2344 2a203afd Seth Mos
	$wlcmd = array();
2345 56626335 Erik Fonnesbeck
	$wl_sysctl = array();
2346 2a203afd Seth Mos
	/* Make sure it's up */
2347
	$wlcmd[] = "up";
2348 ac3f8318 Espen Johansen
	/* Set a/b/g standard */
2349 9be20928 Erik Fonnesbeck
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
2350
	$wlcmd[] = "mode " . escapeshellarg($standard);
2351 2a203afd Seth Mos
2352 5030b5eb Erik Fonnesbeck
	/* XXX: Disable ampdu for now on mwl when running in 11n mode
2353
	 * to prevent massive packet loss under certain conditions. */
2354 9be20928 Erik Fonnesbeck
	if(preg_match("/^mwl/i", $if) && ($standard == "11ng" || $standard == "11na"))
2355 5030b5eb Erik Fonnesbeck
		$wlcmd[] = "-ampdu";
2356
2357 2a203afd Seth Mos
	/* Set ssid */
2358
	if($wlcfg['ssid'])
2359
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
2360 5508cf57 Scott Ullrich
2361 0856c4ac Scott Ullrich
	/* Set 802.11g protection mode */
2362 2a203afd Seth Mos
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
2363 0856c4ac Scott Ullrich
2364 ac3f8318 Espen Johansen
	/* set wireless channel value */
2365 2a203afd Seth Mos
	if(isset($wlcfg['channel'])) {
2366
		if($wlcfg['channel'] == "0") {
2367
			$wlcmd[] = "channel any";
2368
		} else {
2369
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
2370
		}
2371
	}
2372 2ac908dd Espen Johansen
2373 56626335 Erik Fonnesbeck
	/* Set antenna diversity value */
2374
	if(isset($wlcfg['diversity']))
2375
		$wl_sysctl[] = "diversity=" . escapeshellarg($wlcfg['diversity']);
2376
2377
	/* Set txantenna value */
2378
	if(isset($wlcfg['txantenna']))
2379
		$wl_sysctl[] = "txantenna=" . escapeshellarg($wlcfg['txantenna']);
2380
2381
	/* Set rxantenna value */
2382
	if(isset($wlcfg['rxantenna']))
2383
		$wl_sysctl[] = "rxantenna=" . escapeshellarg($wlcfg['rxantenna']);
2384
2385 f134033e Scott Ullrich
	/* set Distance value */
2386 eb772abd Scott Ullrich
	if($wlcfg['distance'])
2387 f134033e Scott Ullrich
		$distance = escapeshellarg($wlcfg['distance']);
2388
2389 ac3f8318 Espen Johansen
	/* Set wireless hostap mode */
2390 2a203afd Seth Mos
	if ($wlcfg['mode'] == "hostap") {
2391
		$wlcmd[] = "mediaopt hostap";
2392
	} else {
2393
		$wlcmd[] = "-mediaopt hostap";
2394
	}
2395 ac3f8318 Espen Johansen
2396
	/* Set wireless adhoc mode */
2397 2a203afd Seth Mos
	if ($wlcfg['mode'] == "adhoc") {
2398
		$wlcmd[] = "mediaopt adhoc";
2399
	} else {
2400
		$wlcmd[] = "-mediaopt adhoc";
2401
	}
2402 ac3f8318 Espen Johansen
2403
	/* Not neccesary to set BSS mode as this is default if adhoc and/or hostap is NOT set */
2404
2405
	/* handle hide ssid option */
2406 2a203afd Seth Mos
	if(isset($wlcfg['hidessid']['enable'])) {
2407
		$wlcmd[] = "hidessid";
2408
	} else {
2409
		$wlcmd[] = "-hidessid";
2410
	}
2411 ac3f8318 Espen Johansen
2412
	/* handle pureg (802.11g) only option */
2413 2a203afd Seth Mos
	if(isset($wlcfg['pureg']['enable'])) {
2414
		$wlcmd[] = "mode 11g pureg";
2415
	} else {
2416
		$wlcmd[] = "-pureg";
2417
	}
2418 ac3f8318 Espen Johansen
2419 ed459692 Erik Fonnesbeck
	/* handle puren (802.11n) only option */
2420
	if(isset($wlcfg['puren']['enable'])) {
2421
		$wlcmd[] = "puren";
2422
	} else {
2423
		$wlcmd[] = "-puren";
2424
	}
2425
2426 ac3f8318 Espen Johansen
	/* enable apbridge option */
2427 2a203afd Seth Mos
	if(isset($wlcfg['apbridge']['enable'])) {
2428
		$wlcmd[] = "apbridge";
2429
	} else {
2430
		$wlcmd[] = "-apbridge";
2431
	}
2432 ac3f8318 Espen Johansen
2433
	/* handle turbo option */
2434 2a203afd Seth Mos
	if(isset($wlcfg['turbo']['enable'])) {
2435
		$wlcmd[] = "mediaopt turbo";
2436
	} else {
2437
		$wlcmd[] = "-mediaopt turbo";
2438
	}
2439 ac3f8318 Espen Johansen
2440
	/* handle txpower setting */
2441 2a203afd Seth Mos
	/* if($wlcfg['txpower'] <> "")
2442
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
2443
	*/
2444 ac3f8318 Espen Johansen
	/* handle wme option */
2445 2a203afd Seth Mos
	if(isset($wlcfg['wme']['enable'])) {
2446
		$wlcmd[] = "wme";
2447
	} else {
2448
		$wlcmd[] = "-wme";
2449
	}
2450 eb772abd Scott Ullrich
2451 ac3f8318 Espen Johansen
	/* set up wep if enabled */
2452 2a203afd Seth Mos
	$wepset = "";
2453
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
2454
		switch($wlcfg['wpa']['auth_algs']) {
2455
			case "1":
2456
				$wepset .= "authmode open wepmode on ";
2457
				break;
2458
			case "2":
2459
				$wepset .= "authmode shared wepmode on ";
2460
				break;
2461
			case "3":
2462
				$wepset .= "authmode mixed wepmode on ";
2463
		}
2464 2f19fa14 Scott Ullrich
		$i = 1;
2465
		foreach ($wlcfg['wep']['key'] as $wepkey) {
2466
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
2467 2a203afd Seth Mos
			if (isset($wepkey['txkey'])) {
2468
				$wlcmd[] = "weptxkey {$i} ";
2469
			}
2470 2f19fa14 Scott Ullrich
			$i++;
2471
		}
2472 2a203afd Seth Mos
		$wlcmd[] = $wepset;
2473
	} else {
2474
		$wlcmd[] = "authmode open wepmode off ";
2475 ac3f8318 Espen Johansen
	}
2476
2477 97f3ce0f Phil Davis
	kill_hostapd($if);
2478 c8178bb7 Erik Fonnesbeck
	mwexec(kill_wpasupplicant("{$if}"));
2479
2480 ac3f8318 Espen Johansen
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2481 2a203afd Seth Mos
	conf_mount_rw();
2482 ac3f8318 Espen Johansen
2483
	switch ($wlcfg['mode']) {
2484 b67d192d Scott Ullrich
		case 'bss':
2485 ac3f8318 Espen Johansen
			if (isset($wlcfg['wpa']['enable'])) {
2486
				$wpa .= <<<EOD
2487 454756b9 Scott Ullrich
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2488 50ad3b7c Scott Ullrich
ctrl_interface_group=0
2489
ap_scan=1
2490 2ac908dd Espen Johansen
#fast_reauth=1
2491 249558a2 Scott Ullrich
network={
2492 454756b9 Scott Ullrich
ssid="{$wlcfg['ssid']}"
2493
scan_ssid=1
2494 2ac908dd Espen Johansen
priority=5
2495
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2496 454756b9 Scott Ullrich
psk="{$wlcfg['wpa']['passphrase']}"
2497 2ac908dd Espen Johansen
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2498
group={$wlcfg['wpa']['wpa_pairwise']}
2499 50ad3b7c Scott Ullrich
}
2500
EOD;
2501
2502 80ec5eaa Scott Ullrich
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
2503 ac3f8318 Espen Johansen
				fwrite($fd, "{$wpa}");
2504
				fclose($fd);
2505
			}
2506 2a203afd Seth Mos
			break;
2507 ac3f8318 Espen Johansen
		case 'hostap':
2508 be45aa79 Renato Botelho
			if($wlcfg['wpa']['passphrase'])
2509 7eadaa9c Scott Ullrich
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
2510 be45aa79 Renato Botelho
			else
2511 abfd0c9b Scott Ullrich
				$wpa_passphrase = "";
2512 ac3f8318 Espen Johansen
			if (isset($wlcfg['wpa']['enable'])) {
2513
				$wpa .= <<<EOD
2514 459d6351 Scott Ullrich
interface={$if}
2515
driver=bsd
2516
logger_syslog=-1
2517
logger_syslog_level=0
2518
logger_stdout=-1
2519
logger_stdout_level=0
2520 2ac908dd Espen Johansen
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
2521
ctrl_interface={$g['varrun_path']}/hostapd
2522 459d6351 Scott Ullrich
ctrl_interface_group=wheel
2523 2ac908dd Espen Johansen
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
2524
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
2525 b67d192d Scott Ullrich
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
2526 459d6351 Scott Ullrich
ssid={$wlcfg['ssid']}
2527 2ac908dd Espen Johansen
debug={$wlcfg['wpa']['debug_mode']}
2528
auth_algs={$wlcfg['wpa']['auth_algs']}
2529
wpa={$wlcfg['wpa']['wpa_mode']}
2530
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2531
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
2532 ac3f8318 Espen Johansen
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
2533
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
2534
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
2535 7eadaa9c Scott Ullrich
{$wpa_passphrase}
2536 525d565b Scott Ullrich
2537 459d6351 Scott Ullrich
EOD;
2538 2ac908dd Espen Johansen
2539 c9e7d30d Scott Ullrich
if (isset($wlcfg['wpa']['rsn_preauth'])) {
2540
	$wpa .= <<<EOD
2541
# Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
2542
rsn_preauth=1
2543
rsn_preauth_interfaces={$if}
2544
2545
EOD;
2546
2547
}
2548 5949124c Scott Ullrich
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
2549
					$auth_server_port = "1812";
2550 be45aa79 Renato Botelho
					if($wlcfg['auth_server_port'])
2551 5949124c Scott Ullrich
						$auth_server_port = $wlcfg['auth_server_port'];
2552 a687f866 Namezero
					$auth_server_port2 = "1812";
2553 be45aa79 Renato Botelho
					if($wlcfg['auth_server_port2'])
2554 a687f866 Namezero
						$auth_server_port2 = $wlcfg['auth_server_port2'];
2555 5949124c Scott Ullrich
					$wpa .= <<<EOD
2556 525d565b Scott Ullrich
2557 5949124c Scott Ullrich
ieee8021x=1
2558
auth_server_addr={$wlcfg['auth_server_addr']}
2559
auth_server_port={$auth_server_port}
2560
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2561 a687f866 Namezero
auth_server_addr={$wlcfg['auth_server_addr2']}
2562
auth_server_port={$auth_server_port2}
2563
auth_server_shared_secret={$wlcfg['auth_server_shared_secret2']}
2564 525d565b Scott Ullrich
2565 459d6351 Scott Ullrich
EOD;
2566 5949124c Scott Ullrich
				} else {
2567
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2568
				}
2569 2ac908dd Espen Johansen
2570 80ec5eaa Scott Ullrich
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
2571 ac3f8318 Espen Johansen
				fwrite($fd, "{$wpa}");
2572
				fclose($fd);
2573 2ac908dd Espen Johansen
2574 ac3f8318 Espen Johansen
			}
2575 2a203afd Seth Mos
			break;
2576 eb772abd Scott Ullrich
	}
2577 ac3f8318 Espen Johansen
2578 4742e927 Scott Ullrich
	/*
2579
	 *    all variables are set, lets start up everything
2580 2a203afd Seth Mos
	 */
2581 eb772abd Scott Ullrich
2582 bbfc810e Erik Fonnesbeck
	$baseif = interface_get_wireless_base($if);
2583 56626335 Erik Fonnesbeck
	preg_match("/^(.*?)([0-9]*)$/", $baseif, $baseif_split);
2584
	$wl_sysctl_prefix = 'dev.' . $baseif_split[1] . '.' . $baseif_split[2];
2585
2586
	/* set sysctls for the wireless interface */
2587
	if (!empty($wl_sysctl)) {
2588
		fwrite($fd_set, "# sysctls for {$baseif}\n");
2589
		foreach ($wl_sysctl as $wl_sysctl_line) {
2590
			fwrite($fd_set, "{$sysctl} {$wl_sysctl_prefix}.{$wl_sysctl_line}\n");
2591
		}
2592
	}
2593 bbfc810e Erik Fonnesbeck
2594 78922914 Scott Ullrich
	/* set ack timers according to users preference (if he/she has any) */
2595
	if($distance) {
2596 4742e927 Scott Ullrich
		fwrite($fd_set, "# Enable ATH distance settings\n");
2597 e327021d Erik Fonnesbeck
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2598 78922914 Scott Ullrich
	}
2599 eb772abd Scott Ullrich
2600 ac3f8318 Espen Johansen
	if (isset($wlcfg['wpa']['enable'])) {
2601 2a203afd Seth Mos
		if ($wlcfg['mode'] == "bss") {
2602 4742e927 Scott Ullrich
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2603 2a203afd Seth Mos
		}
2604
		if ($wlcfg['mode'] == "hostap") {
2605 864bf774 Erik Fonnesbeck
			/* add line to script to restore old mac to make hostapd happy */
2606 acb0bce0 Erik Fonnesbeck
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2607
				$if_oldmac = file_get_contents("{$g['tmp_path']}/{$if}_oldmac");
2608
				if (is_macaddr($if_oldmac))
2609
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2610
						" link " . escapeshellarg($if_oldmac) . "\n");
2611
			}
2612
2613 97f3ce0f Phil Davis
			fwrite($fd_set, "{$hostapd} -B -P {$g['varrun_path']}/hostapd_{$if}.pid {$g['varetc_path']}/hostapd_{$if}.conf\n");
2614 864bf774 Erik Fonnesbeck
2615
			/* add line to script to restore spoofed mac after running hostapd */
2616
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2617
				if ($wl['spoofmac'])
2618
					$if_curmac = $wl['spoofmac'];
2619
				else
2620
					$if_curmac = get_interface_mac($if);
2621
				if (is_macaddr($if_curmac))
2622
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2623
						" link " . escapeshellarg($if_curmac) . "\n");
2624
			}
2625 2a203afd Seth Mos
		}
2626 ac3f8318 Espen Johansen
	}
2627 191a8175 Scott Ullrich
2628 4742e927 Scott Ullrich
	fclose($fd_set);
2629 8a958125 Scott Ullrich
	conf_mount_ro();
2630
2631 bbfc810e Erik Fonnesbeck
	/* Making sure regulatory settings have actually changed
2632
	 * before applying, because changing them requires bringing
2633
	 * down all wireless networks on the interface. */
2634
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2635
	$ifconfig_str = implode($output);
2636
	unset($output);
2637
	$reg_changing = false;
2638
2639 89e7778f Erik Fonnesbeck
	/* special case for the debug country code */
2640
	if ($wlcfg['regcountry'] == 'DEBUG' && !preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str))
2641
		$reg_changing = true;
2642
	else if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
2643 bbfc810e Erik Fonnesbeck
		$reg_changing = true;
2644
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
2645
		$reg_changing = true;
2646 89e7778f Erik Fonnesbeck
	else if ($wlcfg['reglocation'] == 'anywhere' && preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
2647
		$reg_changing = true;
2648 06cb2656 Erik Fonnesbeck
	else if ($wlcfg['reglocation'] && $wlcfg['reglocation'] != 'anywhere' && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
2649 bbfc810e Erik Fonnesbeck
		$reg_changing = true;
2650
2651
	if ($reg_changing) {
2652
		/* set regulatory domain */
2653
		if($wlcfg['regdomain'])
2654
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2655
2656
		/* set country */
2657
		if($wlcfg['regcountry'])
2658
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2659
2660
		/* set location */
2661
		if($wlcfg['reglocation'])
2662
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2663
2664
		$wlregcmd_args = implode(" ", $wlregcmd);
2665
2666
		/* build a complete list of the wireless clones for this interface */
2667
		$clone_list = array();
2668
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
2669
			$clone_list[] = interface_get_wireless_clone($baseif);
2670 6ef2297b Erik Fonnesbeck
		if (isset($config['wireless']['clone']) && is_array($config['wireless']['clone'])) {
2671 bbfc810e Erik Fonnesbeck
			foreach ($config['wireless']['clone'] as $clone) {
2672
				if ($clone['if'] == $baseif)
2673
					$clone_list[] = $clone['cloneif'];
2674
			}
2675
		}
2676
2677
		/* find which clones are up and bring them down */
2678
		$clones_up = array();
2679
		foreach ($clone_list as $clone_if) {
2680 1cf76394 Erik Fonnesbeck
			$clone_status = pfSense_get_interface_addresses($clone_if);
2681 bbfc810e Erik Fonnesbeck
			if ($clone_status['status'] == 'up') {
2682
				$clones_up[] = $clone_if;
2683
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2684
			}
2685
		}
2686
2687
		/* apply the regulatory settings */
2688
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2689
2690
		/* bring the clones back up that were previously up */
2691
		foreach ($clones_up as $clone_if) {
2692
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
2693 67e77adf Erik Fonnesbeck
2694
			/*
2695
			 * Rerun the setup script for the interface if it isn't this interface, the interface
2696
			 * is in infrastructure mode, and WPA is enabled.
2697
			 * This can be removed if wpa_supplicant stops dying when you bring the interface down.
2698
			 */
2699
			if ($clone_if != $if) {
2700
				$friendly_if = convert_real_interface_to_friendly_interface_name($clone_if);
2701
				if ( !empty($friendly_if)
2702
				    && $config['interfaces'][$friendly_if]['wireless']['mode'] == "bss"
2703
				    && isset($config['interfaces'][$friendly_if]['wireless']['wpa']['enable']) ) {
2704
					mwexec("/bin/sh {$g['tmp_path']}/{$clone_if}_setup.sh");
2705
				}
2706
			}
2707 bbfc810e Erik Fonnesbeck
		}
2708
	}
2709
2710 23fdc06e Erik Fonnesbeck
	/* The mode must be specified in a separate command before ifconfig
2711
	 * will allow the mode and channel at the same time in the next. */
2712 9be20928 Erik Fonnesbeck
	mwexec("/sbin/ifconfig {$if} mode " . escapeshellarg($standard));
2713 23fdc06e Erik Fonnesbeck
2714 2a48a885 Erik Fonnesbeck
	/* configure wireless */
2715
	$wlcmd_args = implode(" ", $wlcmd);
2716
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2717
2718 be45aa79 Renato Botelho
2719 2a203afd Seth Mos
	sleep(1);
2720
	/* execute hostapd and wpa_supplicant if required in shell */
2721 6955830f Ermal Lu?i
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
2722 191a8175 Scott Ullrich
2723 ac3f8318 Espen Johansen
	return 0;
2724 cfc707f7 Scott Ullrich
2725 5b237745 Scott Ullrich
}
2726
2727 eba938e3 Scott Ullrich
function kill_hostapd($interface) {
2728 97f3ce0f Phil Davis
	global $g;
2729
2730
	if (isvalidpid("{$g['varrun_path']}/hostapd_{$interface}.pid"))
2731
		return killbypid("{$g['varrun_path']}/hostapd_{$interface}.pid");
2732 4b2a6180 Scott Ullrich
}
2733
2734 eba938e3 Scott Ullrich
function kill_wpasupplicant($interface) {
2735 31b958d5 Erik Fonnesbeck
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\\.conf\"\n";
2736 4b2a6180 Scott Ullrich
}
2737
2738 eba938e3 Scott Ullrich
function find_dhclient_process($interface) {
2739 319cbd5e Ermal
	if ($interface)
2740 05c4bfa0 Ermal
		$pid = `/bin/pgrep -axf "dhclient: {$interface}"`;
2741 319cbd5e Ermal
	else
2742
		$pid = 0;
2743
2744 bcfe4ae5 Ermal
	return intval($pid);
2745 0311dbd5 Scott Ullrich
}
2746
2747 c495f88b Seth Mos
function find_dhcp6c_process($interface) {
2748 b0059636 Ermal
	global $g;
2749
2750 4e6667b2 Renato Botelho
	if ($interface && isvalidpid("{$g['varrun_path']}/dhcp6c_{$interface}.pid"))
2751
		$pid = trim(file_get_contents("{$g['varrun_path']}/dhcp6c_{$interface}.pid"), " \n");
2752
	else
2753 74fa57aa smos
		return(false);
2754 c495f88b Seth Mos
2755
	return intval($pid);
2756
}
2757
2758 4ffa46bf Ermal
function interface_vlan_mtu_configured($realhwif, $mtu) {
2759
	global $config;
2760
2761
	if (is_array($config['vlans']['vlan'])) {
2762
		foreach ($config['vlans']['vlan'] as $vlan) {
2763
			if ($vlan['if'] != $realhwif)
2764
				continue;
2765 a1d36777 Renato Botelho
			$assignedport = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
2766
			if (!empty($assignedport)) {
2767
				$portmtu = $config['interfaces'][$assignedport]['mtu'];
2768 4ffa46bf Ermal
				if (!empty($portmtu) && $portmtu > $mtu)
2769
					$mtu = $portmtu;
2770
			}
2771
		}
2772
	}
2773
2774
	return $mtu;
2775
}
2776
2777 7413cbfd Ermal
function interface_configure($interface = "wan", $reloadall = false, $linkupevent = false) {
2778 675aac3d Ermal Luçi
	global $config, $g;
2779 31b24870 Ermal Luçi
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2780 3502b5b1 Seth Mos
	global $interface_snv6_arr_cache, $interface_ipv6_arr_cache;
2781 cfc707f7 Scott Ullrich
2782 67ee1ec5 Ermal Luçi
	$wancfg = $config['interfaces'][$interface];
2783
2784 e017a46a Ermal
	if (!isset($wancfg['enable']))
2785
		return;
2786
2787 85a5da13 Ermal Luçi
	$realif = get_real_interface($interface);
2788 20cb9803 gnhb
	$realhwif_array = get_parent_interface($interface);
2789
	// Need code to handle MLPPP if we ever use $realhwif for MLPPP handling
2790
	$realhwif = $realhwif_array[0];
2791 cfc707f7 Scott Ullrich
2792 5a3031ea smos
	/* Disable Accepting router advertisements unless specifically requested */
2793 9cd6b950 Ermal
	if ($g['debug'])
2794
		log_error("Deny router advertisements for interface {$interface}");
2795 5a3031ea smos
	mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -accept_rtadv");
2796 be45aa79 Renato Botelho
2797 f382c6de Ermal
	if (!$g['booting'] && !(substr($realif, 0, 4) == "ovpn")) {
2798 3c5e10fc Seth Mos
		/* remove all IPv4 and IPv6 addresses */
2799 332683cb Seth Mos
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2800 3502b5b1 Seth Mos
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -alias", true) == 0);
2801 3896d93e Erik Fonnesbeck
2802 8103bd1e Seth Mos
		/* only bring down the interface when both v4 and v6 are set to NONE */
2803 733829a9 Renato Botelho
		if(empty($wancfg['ipaddr']) && empty($wancfg['ipaddrv6'])) {
2804 8103bd1e Seth Mos
			interface_bring_down($interface);
2805 3896d93e Erik Fonnesbeck
		}
2806 28d22199 Scott Ullrich
	}
2807 acc1e9d0 Scott Ullrich
2808 0a28d385 Erik Fonnesbeck
	/* wireless configuration? */
2809 5b237745 Scott Ullrich
	if (is_array($wancfg['wireless']))
2810 0a28d385 Erik Fonnesbeck
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2811 cfc707f7 Scott Ullrich
2812 49db607f jim-p
	$mac = get_interface_mac($realhwif);
2813 1489e8c8 Renato Botelho
	/*
2814
	 * Don't try to reapply the spoofed MAC if it's already applied.
2815
	 * When ifconfig link is used, it cycles the interface down/up, which triggers
2816
	 * the interface config again, which attempts to spoof the MAC again,
2817
	 * which cycles the link again...
2818
	 */
2819 49db607f jim-p
	if ($wancfg['spoofmac'] && ($wancfg['spoofmac'] != $mac)) {
2820 3e5d0d1d Ermal
		mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2821 5b237745 Scott Ullrich
			" link " . escapeshellarg($wancfg['spoofmac']));
2822 ac8ff0a4 Ermal
2823 1489e8c8 Renato Botelho
		/*
2824
		 * All vlans need to spoof their parent mac address, too.  see
2825
		 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2826
		 */
2827
		if (is_array($config['vlans']['vlan'])) {
2828
			foreach ($config['vlans']['vlan'] as $vlan) {
2829
				if ($vlan['if'] == $realhwif)
2830
					mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2831
					" link " . escapeshellarg($wancfg['spoofmac']));
2832
			}
2833
		}
2834 f36d4bd2 Scott Ullrich
	}  else {
2835 a687f866 Namezero
2836 3e5d0d1d Ermal
		if ($mac == "ff:ff:ff:ff:ff:ff") {
2837 f36d4bd2 Scott Ullrich
			/*   this is not a valid mac address.  generate a
2838
			 *   temporary mac address so the machine can get online.
2839
			 */
2840 07e40c1f Carlos Eduardo Ramos
			echo gettext("Generating new MAC address.");
2841 f36d4bd2 Scott Ullrich
			$random_mac = generate_random_mac_address();
2842 3e5d0d1d Ermal
			mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2843 f36d4bd2 Scott Ullrich
				" link " . escapeshellarg($random_mac));
2844
			$wancfg['spoofmac'] = $random_mac;
2845
			write_config();
2846 addc0439 Renato Botelho
			file_notice("MAC Address altered", sprintf(gettext('The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface %1$s has been automatically replaced with %2$s'), $realif, $random_mac), "Interfaces");
2847 f36d4bd2 Scott Ullrich
		}
2848
	}
2849 cfc707f7 Scott Ullrich
2850 5b237745 Scott Ullrich
	/* media */
2851
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2852 3e5d0d1d Ermal
		$cmd = "/sbin/ifconfig " . escapeshellarg($realhwif);
2853 5b237745 Scott Ullrich
		if ($wancfg['media'])
2854
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2855
		if ($wancfg['mediaopt'])
2856
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2857
		mwexec($cmd);
2858
	}
2859 3e5d0d1d Ermal
	$options = pfSense_get_interface_addresses($realhwif);
2860 9a4c3eed Ermal
2861 51d5aad7 Ermal
	/* skip vlans for checksumming and polling */
2862 7965c38f Ermal
	if (!stristr($realif, "_vlan") && is_array($options)) {
2863 a2dc7392 Renato Botelho
		$flags_on = 0;
2864
		$flags_off = 0;
2865 51d5aad7 Ermal
		if(isset($config['system']['disablechecksumoffloading'])) {
2866
			if (isset($options['encaps']['txcsum']))
2867 a2dc7392 Renato Botelho
				$flags_off |= IFCAP_TXCSUM;
2868 51d5aad7 Ermal
			if (isset($options['encaps']['rxcsum']))
2869 a2dc7392 Renato Botelho
				$flags_off |= IFCAP_RXCSUM;
2870 1489e8c8 Renato Botelho
		} else {
2871 a2dc7392 Renato Botelho
			if (isset($options['caps']['txcsum']))
2872
				$flags_on |= IFCAP_TXCSUM;
2873
			if (isset($options['caps']['rxcsum']))
2874
				$flags_on |= IFCAP_RXCSUM;
2875 1489e8c8 Renato Botelho
		}
2876 51d5aad7 Ermal
2877 a2dc7392 Renato Botelho
		if(isset($config['system']['disablesegmentationoffloading']))
2878
			$flags_off |= IFCAP_TSO;
2879
		else if (isset($options['caps']['tso']) || isset($options['caps']['tso4']) || isset($options['caps']['tso6']))
2880
			$flags_on |= IFCAP_TSO;
2881 51d5aad7 Ermal
2882 a2dc7392 Renato Botelho
		if(isset($config['system']['disablelargereceiveoffloading']))
2883
			$flags_off |= IFCAP_LRO;
2884
		else if (isset($options['caps']['lro']))
2885
			$flags_on |= IFCAP_LRO;
2886 51d5aad7 Ermal
2887 1489e8c8 Renato Botelho
		/* if the NIC supports polling *AND* it is enabled in the GUI */
2888 a2dc7392 Renato Botelho
		if (!isset($config['system']['polling']))
2889
			$flags_off |= IFCAP_POLLING;
2890
		else if (isset($options['caps']['polling']))
2891
			$flags_on |= IFCAP_POLLING;
2892
2893
		pfSense_interface_capabilities($realhwif, -$flags_off);
2894
		pfSense_interface_capabilities($realhwif, $flags_on);
2895 51d5aad7 Ermal
	}
2896
2897 31b24870 Ermal Luçi
	/* invalidate interface/ip/sn cache */
2898 eba938e3 Scott Ullrich
	get_interface_arr(true);
2899 31b24870 Ermal Luçi
	unset($interface_ip_arr_cache[$realif]);
2900
	unset($interface_sn_arr_cache[$realif]);
2901 5a5413bb Seth Mos
	unset($interface_ipv6_arr_cache[$realif]);
2902
	unset($interface_snv6_arr_cache[$realif]);
2903 ccbd2447 Ermal Luçi
2904 5b237745 Scott Ullrich
	switch ($wancfg['ipaddr']) {
2905
		case 'dhcp':
2906 1fb7c265 Ermal Luçi
			interface_dhcp_configure($interface);
2907 5b237745 Scott Ullrich
			break;
2908
		case 'pppoe':
2909 8af6c46d gnhb
		case 'l2tp':
2910 5b237745 Scott Ullrich
		case 'pptp':
2911 9ebe7028 gnhb
		case 'ppp':
2912 64d124c5 gnhb
			interface_ppps_configure($interface);
2913 9ebe7028 gnhb
			break;
2914 5b237745 Scott Ullrich
		default:
2915 8103bd1e Seth Mos
			if (is_ipaddr($wancfg['ipaddr']) && $wancfg['subnet'] <> "") {
2916 871768cf Ermal
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
2917 d1eea523 Ermal
			} else if (substr($realif, 0, 3) == "gre") {
2918
				if (is_array($config['gres']['gre'])) {
2919
					foreach ($config['gres']['gre'] as $gre)
2920
						if ($gre['greif'] == $realif)
2921
							interface_gre_configure($gre);
2922
				}
2923
			} else if (substr($realif, 0, 3) == "gif") {
2924 1489e8c8 Renato Botelho
				if (is_array($config['gifs']['gif'])) {
2925 d1eea523 Ermal
					foreach ($config['gifs']['gif'] as $gif)
2926 d1ae9705 Ermal
						if($gif['gifif'] == $realif)
2927 d1eea523 Ermal
							interface_gif_configure($gif);
2928
				}
2929
			} else if (substr($realif, 0, 4) == "ovpn") {
2930
				/* XXX: Should be done anything?! */
2931 acc1e9d0 Scott Ullrich
			}
2932 d1eea523 Ermal
			break;
2933 5b237745 Scott Ullrich
	}
2934 ffeb5acf Scott Ullrich
2935 5a5413bb Seth Mos
	switch ($wancfg['ipaddrv6']) {
2936 feb88a14 smos
		case 'slaac':
2937 8103bd1e Seth Mos
		case 'dhcp6':
2938 7a04cd20 Ermal
			interface_dhcpv6_configure($interface, $wancfg);
2939 8103bd1e Seth Mos
			break;
2940 3f383504 smos
		case '6rd':
2941 7a04cd20 Ermal
			interface_6rd_configure($interface, $wancfg);
2942 3f383504 smos
			break;
2943 31c43fd3 smos
		case '6to4':
2944 7a04cd20 Ermal
			interface_6to4_configure($interface, $wancfg);
2945 31c43fd3 smos
			break;
2946 20a7cb15 smos
		case 'track6':
2947 d1878053 Renato Botelho
			interface_track6_configure($interface, $wancfg);
2948 20a7cb15 smos
			break;
2949 5a5413bb Seth Mos
		default:
2950 8103bd1e Seth Mos
			if (is_ipaddr($wancfg['ipaddrv6']) && $wancfg['subnetv6'] <> "") {
2951 5a5413bb Seth Mos
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddrv6']}/{$wancfg['subnetv6']}");
2952 3c5e10fc Seth Mos
				// FIXME: Add IPv6 Support to the pfSense module
2953 5a5413bb Seth Mos
				mwexec("/sbin/ifconfig {$realif} inet6 {$wancfg['ipaddrv6']} prefixlen {$wancfg['subnetv6']} ");
2954
			}
2955
			break;
2956
	}
2957
2958 4a735210 Renato Botelho
	$mtu = get_interface_default_mtu(remove_ifindex($realhwif));
2959 20eb8203 Renato Botelho
	$assignedparent = convert_real_interface_to_friendly_interface_name($realhwif);
2960 08e9c732 Ermal
	if (!empty($assignedparent) && !empty($config['interfaces'][$assignedparent]['mtu']))
2961 20eb8203 Renato Botelho
		$mtu = $config['interfaces'][$assignedparent]['mtu'];
2962 4a735210 Renato Botelho
2963 a976c633 Renato Botelho
	$vlanifs = link_interface_to_vlans($realhwif);
2964
	if (empty($vlanifs))
2965
		$vlanifs = array();
2966
2967 d35233da Ermal
	if (!empty($wancfg['mtu'])) {
2968 7965c38f Ermal
		if (stristr($realif, "_vlan")) {
2969 a1d36777 Renato Botelho
			if (!empty($assignedparent)) {
2970
				$parentmtu = $config['interfaces'][$assignedparent]['mtu'];
2971 d35233da Ermal
				if (empty($parentmtu))
2972 6d1594eb Ermal
					$parentmtu = interface_vlan_mtu_configured($realhwif, $wancfg['mtu']);
2973 2fff3ba2 Ermal
				if ($wancfg['mtu'] > $parentmtu) {
2974 43c6c9af Renato Botelho
					if (get_interface_mtu($realhwif) != $wancfg['mtu'])
2975
						pfSense_interface_mtu($realhwif, $wancfg['mtu']);
2976 2fff3ba2 Ermal
2977
					/* All vlans need to use the same mtu value as their parent. */
2978 a976c633 Renato Botelho
					foreach ($vlanifs as $vlan) {
2979
						if ($vlan['vlanif'] == $realif)
2980
							continue;
2981
						$assignedport = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
2982
						if (!empty($assignedport)) {
2983
							$portmtu = $config['interfaces'][$assignedport]['mtu'];
2984 43c6c9af Renato Botelho
							if (empty($portmtu) && (get_interface_mtu($vlan['vlanif']) != $wancfg['mtu']))
2985 2fff3ba2 Ermal
								pfSense_interface_mtu($vlan['vlanif'], $wancfg['mtu']);
2986 43c6c9af Renato Botelho
						} else if (get_interface_mtu($vlan['vlanif']) != $wancfg['mtu'])
2987 a976c633 Renato Botelho
							pfSense_interface_mtu($vlan['vlanif'], $wancfg['mtu']);
2988 2fff3ba2 Ermal
					}
2989
				}
2990 4ffa46bf Ermal
			} else {
2991 be2c39b6 Renato Botelho
				/* Parent is not assigned, back to default */
2992
				if (get_interface_mtu($realhwif) != $mtu)
2993
					pfSense_interface_mtu($realhwif, $mtu);
2994
2995
				/* All vlans need to use the same mtu value as their parent. */
2996
				foreach ($vlanifs as $vlan) {
2997
					if ($vlan['vlanif'] == $realif)
2998
						continue;
2999
					$assignedport = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
3000
					if (!empty($assignedport)) {
3001
						$portmtu = $config['interfaces'][$assignedport]['mtu'];
3002 43c6c9af Renato Botelho
						if (empty($portmtu) && (get_interface_mtu($vlan['vlanif']) != $mtu))
3003 be2c39b6 Renato Botelho
							pfSense_interface_mtu($vlan['vlanif'], $mtu);
3004 43c6c9af Renato Botelho
					} else if (get_interface_mtu($vlan['vlanif']) != $mtu)
3005 be2c39b6 Renato Botelho
						pfSense_interface_mtu($vlan['vlanif'], $mtu);
3006 4ffa46bf Ermal
				}
3007 be2c39b6 Renato Botelho
3008
				if (get_interface_mtu($realif) != $wancfg['mtu'])
3009
					pfSense_interface_mtu($realif, $wancfg['mtu']);
3010 4ffa46bf Ermal
			}
3011 a362a23a Ermal
		} else {
3012 a976c633 Renato Botelho
			foreach ($vlanifs as $vlan) {
3013
				$assignedport = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
3014 43c6c9af Renato Botelho
				if (empty($assignedport)) {
3015
					if (get_interface_mtu($vlan['vlanif']) != $wancfg['mtu'])
3016
						pfSense_interface_mtu($vlan['vlanif'], $wancfg['mtu']);
3017
				} else {
3018 a976c633 Renato Botelho
					$vlanmtu = $config['interfaces'][$assignedport]['mtu'];
3019 f5c2bf1e Renato Botelho
					if ((empty($vlanmtu) || ($vlanmtu >= $wancfg['mtu'])) && (get_interface_mtu($vlan['vlanif']) != $wancfg['mtu']))
3020 a362a23a Ermal
						pfSense_interface_mtu($vlan['vlanif'], $wancfg['mtu']);
3021
				}
3022
			}
3023 1e08ce64 Ermal
		}
3024
		if ($wancfg['mtu'] != get_interface_mtu($realif))
3025 b1939343 Ermal
			pfSense_interface_mtu($realif, $wancfg['mtu']);
3026 76254caa Renato Botelho
	} else if (stristr($realif, "_vlan")) {
3027 59297ade Ermal
		/* XXX: This is really dangerous for example with vlans changing their parent mtu! */
3028 4ffa46bf Ermal
		$bigmtu = interface_vlan_mtu_configured($realhwif, $mtu);
3029
		if ($mtu < $bigmtu)
3030
			$mtu = $bigmtu;
3031 43c6c9af Renato Botelho
3032
		if (get_interface_mtu($realhwif) != $mtu)
3033
			pfSense_interface_mtu($realhwif, $mtu);
3034 4ffa46bf Ermal
3035
		/* All vlans need to use the same mtu value as their parent. */
3036 a976c633 Renato Botelho
		foreach ($vlanifs as $vlan) {
3037
			if ($vlan['vlanif'] == $realif)
3038
				continue;
3039
			$assignedport = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
3040
			if (!empty($assignedport)) {
3041
				$portmtu = $config['interfaces'][$assignedport]['mtu'];
3042 43c6c9af Renato Botelho
				if (empty($portmtu) && (get_interface_mtu($vlan['vlanif']) != $mtu))
3043 1dedfdd1 Ermal
					pfSense_interface_mtu($vlan['vlanif'], $mtu);
3044 43c6c9af Renato Botelho
			} else if (get_interface_mtu($vlan['vlanif']) != $mtu)
3045 a976c633 Renato Botelho
				pfSense_interface_mtu($vlan['vlanif'], $mtu);
3046 4ffa46bf Ermal
		}
3047 43c6c9af Renato Botelho
		if (get_interface_mtu($realif) != $mtu)
3048
			pfSense_interface_mtu($realif, $mtu);
3049 3f3252f6 Renato Botelho
	} else {
3050
		/* All vlans need to use the same mtu value as their parent. */
3051
		foreach ($vlanifs as $vlan) {
3052
			$assignedport = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
3053
			if (!empty($assignedport)) {
3054
				$portmtu = $config['interfaces'][$assignedport]['mtu'];
3055 43c6c9af Renato Botelho
				if (empty($portmtu) && (get_interface_mtu($vlan['vlanif']) != $mtu))
3056 3f3252f6 Renato Botelho
					pfSense_interface_mtu($vlan['vlanif'], $mtu);
3057 43c6c9af Renato Botelho
			} else if (get_interface_mtu($vlan['vlanif']) != $mtu)
3058 3f3252f6 Renato Botelho
				pfSense_interface_mtu($vlan['vlanif'], $mtu);
3059
		}
3060
		if ($mtu != get_interface_mtu($realhwif))
3061
			pfSense_interface_mtu($realhwif, $mtu);
3062
	}
3063 4a735210 Renato Botelho
3064 a976c633 Renato Botelho
	unset($vlanifs);
3065
3066 435f11c8 Ermal Lu?i
	if(does_interface_exist($wancfg['if']))
3067 7284d850 Scott Ullrich
		interfaces_bring_up($wancfg['if']);
3068 67b057a9 Ermal
3069
	interface_netgraph_needed($interface);
3070 be45aa79 Renato Botelho
3071 5b237745 Scott Ullrich
	if (!$g['booting']) {
3072 dcadda55 Ermal
		link_interface_to_vips($interface, "update");
3073 6991dcb1 Ermal
3074 a639bb91 Ermal
		unset($gre);
3075
		$gre = link_interface_to_gre($interface);
3076
		if (!empty($gre))
3077 ed62880b Ermal
			array_walk($gre, 'interface_gre_configure');
3078 a639bb91 Ermal
3079
		unset($gif);
3080
		$gif = link_interface_to_gif($interface);
3081
		if (!empty($gif))
3082 8103bd1e Seth Mos
			array_walk($gif, 'interface_gif_configure');
3083 a639bb91 Ermal
3084 bf17eb72 Ermal
		if ($linkupevent == false || substr($realif, 0, 4) == "ovpn") {
3085 7413cbfd Ermal
			unset($bridgetmp);
3086
			$bridgetmp = link_interface_to_bridge($interface);
3087
			if (!empty($bridgetmp))
3088
				interface_bridge_add_member($bridgetmp, $realif);
3089
		}
3090 ccbd2447 Ermal Luçi
3091 48f23632 Ermal
		$grouptmp = link_interface_to_group($interface);
3092
		if (!empty($grouptmp))
3093 ed62880b Ermal
			array_walk($grouptmp, 'interface_group_add_member');
3094 48f23632 Ermal
3095 a5d6f60b Ermal Lu?i
		if ($interface == "lan")
3096 4476d447 Ermal Luçi
			/* make new hosts file */
3097 ffeb5acf Scott Ullrich
			system_hosts_generate();
3098 4476d447 Ermal Luçi
3099 a5d6f60b Ermal Lu?i
		if ($reloadall == true) {
3100 cfc707f7 Scott Ullrich
3101 a5d6f60b Ermal Lu?i
			/* reconfigure static routes (kernel may have deleted them) */
3102 1ea67f2e Ermal
			system_routing_configure($interface);
3103 cfc707f7 Scott Ullrich
3104 a5d6f60b Ermal Lu?i
			/* reload ipsec tunnels */
3105
			vpn_ipsec_configure();
3106 cfc707f7 Scott Ullrich
3107 b5eeef07 Ermal
			/* restart dnsmasq */
3108
			services_dnsmasq_configure();
3109
3110 a5d6f60b Ermal Lu?i
			/* update dyndns */
3111 422bc2a7 Ermal
			send_event("service reload dyndns {$interface}");
3112 a23d7248 Scott Ullrich
3113 a5d6f60b Ermal Lu?i
			/* reload captive portal */
3114 769e254e Ermal
			captiveportal_init_rules();
3115 a5d6f60b Ermal Lu?i
		}
3116 5b237745 Scott Ullrich
	}
3117 cfc707f7 Scott Ullrich
3118 c1d8c235 Renato Botelho
	interfaces_staticarp_configure($interface);
3119 5b237745 Scott Ullrich
	return 0;
3120
}
3121
3122 7a04cd20 Ermal
function interface_track6_configure($interface = "lan", $wancfg) {
3123 20a7cb15 smos
	global $config, $g;
3124
3125 7a04cd20 Ermal
	if (!is_array($wancfg))
3126
		return;
3127
3128
	if (!isset($wancfg['enable']))
3129 b0059636 Ermal
		return;
3130 be45aa79 Renato Botelho
3131 20a7cb15 smos
	/* If the interface is not configured via another, exit */
3132 b0059636 Ermal
	if (empty($wancfg['track6-interface']))
3133
		return;
3134 20a7cb15 smos
3135 e90c833a smos
	/* always configure a link-local of fe80::1:1 on the track6 interfaces */
3136
	$realif = get_real_interface($interface);
3137 919ff1f0 Ermal
	$linklocal = find_interface_ipv6_ll($realif);
3138 6d49e2ba Renato Botelho
	if (!empty($linklocal))
3139 919ff1f0 Ermal
		mwexec("/sbin/ifconfig {$realif} inet6 {$linklocal} delete");
3140 e90c833a smos
	mwexec("/sbin/ifconfig {$realif} inet6 fe80::1:1%{$realif}");
3141
3142 7a04cd20 Ermal
	$trackcfg = $config['interfaces'][$wancfg['track6-interface']];
3143
	if (!isset($trackcfg['enable'])) {
3144
		log_error("Interface {$interface} tracking non-existant interface {$wancfg['track6-interface']}");
3145
		return;
3146
	}
3147
3148
	switch($trackcfg['ipaddrv6']) {
3149 6fb66736 Ermal
	case "6to4":
3150
		if ($g['debug'])
3151
			log_error("Interface {$interface} configured via {$wancfg['track6-interface']}  type {$type}");
3152
		interface_track6_6to4_configure($interface, $wancfg);
3153
		break;
3154
	case "6rd":
3155
		if ($g['debug'])
3156
			log_error("Interface {$interface} configured via {$wancfg['track6-interface']}  type {$type}");
3157
		interface_track6_6rd_configure($interface, $wancfg);
3158
		break;
3159 20a7cb15 smos
	}
3160 b0059636 Ermal
3161 7fd67662 Ermal
	if (!$g['booting']) {
3162
		if (!function_exists('services_dhcpd_configure'))
3163
			require_once("services.inc");
3164 6387590f Ermal
3165 7fd67662 Ermal
		services_dhcpd_configure("inet6");
3166
	}
3167 6387590f Ermal
3168 20a7cb15 smos
	return 0;
3169
}
3170
3171 7a04cd20 Ermal
function interface_track6_6rd_configure($interface = "lan", $lancfg) {
3172 20a7cb15 smos
	global $config, $g;
3173 da9dd1b4 Ermal
	global $interface_ipv6_arr_cache;
3174 a8f5790a Renato Botelho
	global $interface_snv6_arr_cache;
3175 20a7cb15 smos
3176 7a04cd20 Ermal
	if (!is_array($lancfg))
3177 b0059636 Ermal
		return;
3178 be45aa79 Renato Botelho
3179 20a7cb15 smos
	/* If the interface is not configured via another, exit */
3180 b0059636 Ermal
	if (empty($lancfg['track6-interface']))
3181
		return;
3182
3183 20a7cb15 smos
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
3184 7a04cd20 Ermal
	if (empty($wancfg)) {
3185
		log_error("Interface {$interface} tracking non-existant interface {$lancfg['track6-interface']}");
3186 b0059636 Ermal
		return;
3187 7a04cd20 Ermal
	}
3188 be45aa79 Renato Botelho
3189 ff5674dc Ermal
	$ip4address = get_interface_ip($lancfg['track6-interface']);
3190 7a04cd20 Ermal
	if (!is_ipaddrv4($ip4address)) { /* XXX: This should not be needed by 6rd || (is_private_ip($ip4address))) { */
3191 ff5674dc Ermal
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$lancfg['track6-interface']}' is not public, not configuring 6RD tunnel");
3192 b0059636 Ermal
		return;
3193 20a7cb15 smos
	}
3194
	$hexwanv4 = return_hex_ipv4($ip4address);
3195 be45aa79 Renato Botelho
3196 20a7cb15 smos
	/* create the long prefix notation for math, save the prefix length */
3197
	$rd6prefix = explode("/", $wancfg['prefix-6rd']);
3198
	$rd6prefixlen = $rd6prefix[1];
3199
	$rd6prefix = Net_IPv6::uncompress($rd6prefix[0]);
3200
3201
	/* binary presentation of the prefix for all 128 bits. */
3202
	$rd6lanbin = convert_ipv6_to_128bit($rd6prefix);
3203 be45aa79 Renato Botelho
3204 20a7cb15 smos
	/* just save the left prefix length bits */
3205
	$rd6lanbin = substr($rd6lanbin, 0, $rd6prefixlen);
3206
	/* add the v4 address, offset n bits from the left */
3207
	$rd6lanbin .= substr(sprintf("%032b", hexdec($hexwanv4)), (0 + $wancfg['prefix-6rd-v4plen']), 32);
3208
3209
	/* add the custom prefix id, max 32bits long? (64 bits - (prefixlen + (32 - v4plen)) */
3210
	/* 64 - (37 + (32 - 17)) = 8 == /52 */
3211
	$restbits = 64 - ($rd6prefixlen + (32 - $wancfg['prefix-6rd-v4plen']));
3212
	// echo "64 - (prefixlen {$rd6prefixlen} + v4len (32 - {$wancfg['prefix-6rd-v4plen']})) = {$restbits} \n";
3213
	$rd6lanbin .= substr(sprintf("%032b", str_pad($lancfg['track6-prefix-id'], 32, "0", STR_PAD_LEFT)), (32 - $restbits), 32);
3214
	/* fill the rest out with zeros */
3215
	$rd6lanbin = str_pad($rd6lanbin, 128, "0", STR_PAD_RIGHT);;
3216
3217 be45aa79 Renato Botelho
	/* convert the 128 bits for the lan address back into a valid IPv6 address */
3218 20a7cb15 smos
	$rd6lan = convert_128bit_to_ipv6($rd6lanbin) ."1";
3219 be45aa79 Renato Botelho
3220 b0059636 Ermal
	$lanif = get_real_interface($interface);
3221 c4fc2eae Ermal
	$oip = find_interface_ipv6($lanif);
3222
	if (is_ipaddrv6($oip))
3223
		mwexec("/sbin/ifconfig {$lanif} inet6 {$oip} delete");
3224 da9dd1b4 Ermal
	unset($interface_ipv6_arr_cache[$lanif]);
3225
	unset($interface_snv6_arr_cache[$lanif]);
3226 20a7cb15 smos
	log_error("rd6 {$interface} with ipv6 address {$rd6lan} based on {$lancfg['track6-interface']} ipv4 {$ip4address}");
3227
	mwexec("/sbin/ifconfig {$lanif} inet6 {$rd6lan} prefixlen 64");
3228 b0059636 Ermal
3229 20a7cb15 smos
	return 0;
3230
}
3231
3232 7a04cd20 Ermal
function interface_track6_6to4_configure($interface = "lan", $lancfg) {
3233 20a7cb15 smos
	global $config, $g;
3234 da9dd1b4 Ermal
	global $interface_ipv6_arr_cache;
3235 a8f5790a Renato Botelho
	global $interface_snv6_arr_cache;
3236 20a7cb15 smos
3237 7a04cd20 Ermal
	if (!is_array($lancfg))
3238 b0059636 Ermal
		return;
3239 be45aa79 Renato Botelho
3240 20a7cb15 smos
	/* If the interface is not configured via another, exit */
3241 b0059636 Ermal
	if (empty($lancfg['track6-interface']))
3242
		return;
3243
3244 7a04cd20 Ermal
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
3245
	if (empty($wancfg)) {
3246
		log_error("Interface {$interface} tracking non-existant interface {$lancfg['track6-interface']}");
3247
		return;
3248
	}
3249
3250 ff5674dc Ermal
	$ip4address = get_interface_ip($lancfg['track6-interface']);
3251 b0059636 Ermal
	if (!is_ipaddrv4($ip4address) || is_private_ip($ip4address)) {
3252 ff5674dc Ermal
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$lancfg['track6-interface']}' is not public, not configuring 6RD tunnel");
3253 b0059636 Ermal
		return;
3254 20a7cb15 smos
	}
3255
	$hexwanv4 = return_hex_ipv4($ip4address);
3256 be45aa79 Renato Botelho
3257 20a7cb15 smos
	/* create the long prefix notation for math, save the prefix length */
3258
	$sixto4prefix = "2002::";
3259
	$sixto4prefixlen = 16;
3260
	$sixto4prefix = Net_IPv6::uncompress($sixto4prefix);
3261
3262
	/* binary presentation of the prefix for all 128 bits. */
3263
	$sixto4lanbin = convert_ipv6_to_128bit($sixto4prefix);
3264 be45aa79 Renato Botelho
3265 20a7cb15 smos
	/* just save the left prefix length bits */
3266
	$sixto4lanbin = substr($sixto4lanbin, 0, $sixto4prefixlen);
3267
	/* add the v4 address */
3268
	$sixto4lanbin .= sprintf("%032b", hexdec($hexwanv4));
3269
	/* add the custom prefix id */
3270
	$sixto4lanbin .= sprintf("%016b", $lancfg['track6-prefix-id']);
3271
	/* fill the rest out with zeros */
3272
	$sixto4lanbin = str_pad($sixto4lanbin, 128, "0", STR_PAD_RIGHT);;
3273 be45aa79 Renato Botelho
3274
	/* convert the 128 bits for the lan address back into a valid IPv6 address */
3275 20a7cb15 smos
	$sixto4lan = convert_128bit_to_ipv6($sixto4lanbin) ."1";
3276 be45aa79 Renato Botelho
3277 b0059636 Ermal
	$lanif = get_real_interface($interface);
3278 c4fc2eae Ermal
	$oip = find_interface_ipv6($lanif);
3279
	if (is_ipaddrv6($oip))
3280
		mwexec("/sbin/ifconfig {$lanif} inet6 {$oip} delete");
3281 da9dd1b4 Ermal
	unset($interface_ipv6_arr_cache[$lanif]);
3282
	unset($interface_snv6_arr_cache[$lanif]);
3283 20a7cb15 smos
	log_error("sixto4 {$interface} with ipv6 address {$sixto4lan} based on {$lancfg['track6-interface']} ipv4 {$ip4address}");
3284
	mwexec("/sbin/ifconfig {$lanif} inet6 {$sixto4lan} prefixlen 64");
3285 b0059636 Ermal
3286 20a7cb15 smos
	return 0;
3287
}
3288
3289 7a04cd20 Ermal
function interface_6rd_configure($interface = "wan", $wancfg) {
3290 668e8961 smos
	global $config, $g;
3291
3292 be45aa79 Renato Botelho
	/* because this is a tunnel interface we can only function
3293 668e8961 smos
	 *	with a public IPv4 address on the interface */
3294
3295 7a04cd20 Ermal
	if (!is_array($wancfg))
3296 b0059636 Ermal
		return;
3297 668e8961 smos
3298
	$wanif = get_real_interface($interface);
3299
	$ip4address = find_interface_ip($wanif);
3300 b0059636 Ermal
	if ((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
3301 668e8961 smos
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
3302 1f78ab3a smos
		return false;
3303 668e8961 smos
	}
3304 20a7cb15 smos
	$hexwanv4 = return_hex_ipv4($ip4address);
3305 be45aa79 Renato Botelho
3306 b0059636 Ermal
	if (!is_numeric($wancfg['prefix-6rd-v4plen']))
3307 20a7cb15 smos
		$wancfg['prefix-6rd-v4plen'] = 0;
3308 668e8961 smos
3309 51c57aae smos
	/* create the long prefix notation for math, save the prefix length */
3310 f87ccbed smos
	$rd6prefix = explode("/", $wancfg['prefix-6rd']);
3311
	$rd6prefixlen = $rd6prefix[1];
3312
	$rd6prefix = Net_IPv6::uncompress($rd6prefix[0]);
3313 51c57aae smos
3314
	/* binary presentation of the prefix for all 128 bits. */
3315 20a7cb15 smos
	$rd6prefixbin = convert_ipv6_to_128bit($rd6prefix);
3316 be45aa79 Renato Botelho
3317 51c57aae smos
	/* just save the left prefix length bits */
3318 20a7cb15 smos
	$rd6prefixbin = substr($rd6prefixbin, 0, $rd6prefixlen);
3319 51c57aae smos
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3320 4aa569bd smos
	$rd6prefixbin .= substr(sprintf("%032b", hexdec($hexwanv4)), $wancfg['prefix-6rd-v4plen'], 32);
3321 20a7cb15 smos
	/* fill out the rest with 0's */
3322
	$rd6prefixbin = str_pad($rd6prefixbin, 128, "0", STR_PAD_RIGHT);;
3323 51c57aae smos
3324 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3325 4aa569bd smos
	$rd6prefix = convert_128bit_to_ipv6($rd6prefixbin);
3326 f87ccbed smos
3327 07615045 Ermal
	$rd6brgw = "{$rd6prefix}{$wancfg['gateway-6rd']}";
3328 733c6f89 Ermal
3329 7d1f2eac Ermal
	/* XXX: need to extend to support variable prefix size for v4 */
3330 b686e5d0 Ermal
	if (!is_module_loaded("if_stf"))
3331
		mwexec("/sbin/kldload if_stf.ko");
3332 7d1f2eac Ermal
	$stfiface = "{$interface}_stf";
3333 c4fc2eae Ermal
	if (does_interface_exist($stfiface))
3334
		pfSense_interface_destroy($stfiface);
3335
	$tmpstfiface = pfSense_interface_create("stf");
3336
	pfSense_interface_rename($tmpstfiface, $stfiface);
3337 7d1f2eac Ermal
	pfSense_interface_flags($stfiface, IFF_LINK2);
3338
	mwexec("/sbin/ifconfig {$stfiface} inet6 {$rd6prefix}/{$rd6prefixlen}");
3339 8959f2fc Ermal
	mwexec("/sbin/ifconfig {$stfiface} stfv4br " . escapeshellarg($wancfg['gateway-6rd']));
3340 d9377608 Ermal
	if ($wancfg['prefix-6rd-v4plen'] > 0 && $wancfg['prefix-6rd-v4plen'] < 32)
3341 733c6f89 Ermal
		mwexec("/sbin/ifconfig {$stfiface} stfv4net {$ip4address}/{$wancfg['prefix-6rd-v4plen']}");
3342 b0059636 Ermal
	if ($g['debug'])
3343 7d1f2eac Ermal
		log_error("Created 6rd interface {$stfiface} {$rd6prefix}/{$rd6prefixlen}");
3344 668e8961 smos
3345 f55b6cbb smos
	/* write out a default router file */
3346 20a7cb15 smos
	file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$rd6brgw}\n");
3347
	file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$rd6brgw}\n");
3348 2d5ca06e smos
3349 5ee79d32 Ermal
	$ip4gateway = get_interface_gateway($interface);
3350 66c73aab Ermal
	if (is_ipaddrv4($ip4gateway))
3351 87dfd826 Ermal
		mwexec("/sbin/route change -host " . escapeshellarg($wancfg['gateway-6rd']) . " {$ip4gateway}");
3352 c8ed8142 smos
3353 2d5ca06e smos
	/* configure dependent interfaces */
3354 7a04cd20 Ermal
	if (!$g['booting'])
3355
		link_interface_to_track6($interface, "update");
3356 66c73aab Ermal
3357 f55b6cbb smos
	return 0;
3358 668e8961 smos
}
3359
3360 7a04cd20 Ermal
function interface_6to4_configure($interface = "wan", $wancfg){
3361 31c43fd3 smos
	global $config, $g;
3362
3363 be45aa79 Renato Botelho
	/* because this is a tunnel interface we can only function
3364 31c43fd3 smos
	 *	with a public IPv4 address on the interface */
3365
3366 7a04cd20 Ermal
	if (!is_array($wancfg))
3367
		return;
3368 31c43fd3 smos
3369
	$wanif = get_real_interface($interface);
3370
	$ip4address = find_interface_ip($wanif);
3371
	if((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
3372
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
3373
		return false;
3374
	}
3375 be45aa79 Renato Botelho
3376 31c43fd3 smos
	/* create the long prefix notation for math, save the prefix length */
3377
	$stfprefixlen = 16;
3378
	$stfprefix = Net_IPv6::uncompress("2002::");
3379
	$stfarr = explode(":", $stfprefix);
3380
	$v4prefixlen = "0";
3381 be45aa79 Renato Botelho
3382 31c43fd3 smos
	/* we need the hex form of the interface IPv4 address */
3383
	$ip4arr = explode(".", $ip4address);
3384
	$hexwanv4 = "";
3385
	foreach($ip4arr as $octet)
3386
		$hexwanv4 .= sprintf("%02x", $octet);
3387
3388
	/* we need the hex form of the broker IPv4 address */
3389
	$ip4arr = explode(".", "192.88.99.1");
3390
	$hexbrv4 = "";
3391
	foreach($ip4arr as $octet)
3392
		$hexbrv4 .= sprintf("%02x", $octet);
3393 be45aa79 Renato Botelho
3394 31c43fd3 smos
	/* binary presentation of the prefix for all 128 bits. */
3395
	$stfprefixbin = "";
3396
	foreach($stfarr as $element) {
3397
		$stfprefixbin .= sprintf("%016b", hexdec($element));
3398
	}
3399
	/* just save the left prefix length bits */
3400
	$stfprefixstartbin = substr($stfprefixbin, 0, $stfprefixlen);
3401
3402
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3403
	$stfbrokerbin = substr(sprintf("%032b", hexdec($hexbrv4)), $v4prefixlen, 32);
3404
	$stfbrokerbin = str_pad($stfprefixstartbin . $stfbrokerbin, 128, "0", STR_PAD_RIGHT);;
3405
3406
	/* for the local subnet too. */
3407
	$stflanbin = substr(sprintf("%032b", hexdec($hexwanv4)), $v4prefixlen, 32);
3408
	$stflanbin = str_pad($stfprefixstartbin . $stflanbin, 128, "0", STR_PAD_RIGHT);;
3409
3410 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3411 31c43fd3 smos
	$stfbrarr = array();
3412
	$stfbrbinarr = array();
3413
	$stfbrbinarr = str_split($stfbrokerbin, 16);
3414
	foreach($stfbrbinarr as $bin)
3415
		$stfbrarr[] = dechex(bindec($bin));
3416
	$stfbrgw = Net_IPv6::compress(implode(":", $stfbrarr));
3417
3418 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3419 31c43fd3 smos
	$stflanarr = array();
3420
	$stflanbinarr = array();
3421
	$stflanbinarr = str_split($stflanbin, 16);
3422
	foreach($stflanbinarr as $bin)
3423
		$stflanarr[] = dechex(bindec($bin));
3424
	$stflanpr = Net_IPv6::compress(implode(":", $stflanarr));
3425
	$stflanarr[7] = 1;
3426
	$stflan = Net_IPv6::compress(implode(":", $stflanarr));
3427
3428
	/* setup the stf interface */
3429 b686e5d0 Ermal
	if (!is_module_loaded("if_stf"))
3430
		mwexec("/sbin/kldload if_stf.ko");
3431 7d1f2eac Ermal
	$stfiface = "{$interface}_stf";
3432 c4fc2eae Ermal
	if (does_interface_exist($stfiface))
3433
		pfSense_interface_destroy($stfiface);
3434
	$tmpstfiface = pfSense_interface_create("stf");
3435
	pfSense_interface_rename($tmpstfiface, $stfiface);
3436 7d1f2eac Ermal
	pfSense_interface_flags($stfiface, IFF_LINK2);
3437
	mwexec("/sbin/ifconfig {$stfiface} inet6 {$stflanpr} prefixlen 16");
3438 31c43fd3 smos
3439 7d1f2eac Ermal
	if ($g['debug'])
3440
		log_error("Set IPv6 address inet6 {$stflanpr} prefixlen 16 for {$stfiface}, route {$stfbrgw}");
3441 be45aa79 Renato Botelho
3442 31c43fd3 smos
	/* write out a default router file */
3443
	file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$stfbrgw}");
3444
	file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$stfbrgw}");
3445 2d5ca06e smos
3446 5ee79d32 Ermal
	$ip4gateway = get_interface_gateway($interface);
3447
	if (is_ipaddrv4($ip4gateway))
3448 85a389c9 Ermal
		mwexec("/sbin/route change -host 192.88.99.1 {$ip4gateway}");
3449 c8ed8142 smos
3450 7a04cd20 Ermal
	if (!$g['booting'])
3451
		link_interface_to_track6($interface, "update");
3452 be45aa79 Renato Botelho
3453 31c43fd3 smos
	return 0;
3454
}
3455
3456 7a04cd20 Ermal
function interface_dhcpv6_configure($interface = "wan", $wancfg) {
3457 ed395640 Seth Mos
	global $config, $g;
3458
3459 7a04cd20 Ermal
	if (!is_array($wancfg))
3460 b0059636 Ermal
		return;
3461 ed395640 Seth Mos
3462 10054843 Ermal
	$wanif = get_real_interface($interface, "inet6");
3463 d53a9a51 smos
	$dhcp6cconf = "";
3464
	$dhcp6cconf .= "interface {$wanif} {\n";
3465 feb88a14 smos
3466 d53a9a51 smos
	/* for SLAAC interfaces we do fire off a dhcp6 client for just our name servers */
3467
	if($wancfg['ipaddrv6'] == "slaac") {
3468
		$dhcp6cconf .= "	information-only;\n";
3469
		$dhcp6cconf .= "	request domain-name-servers;\n";
3470
		$dhcp6cconf .= "	request domain-name;\n";
3471
		$dhcp6cconf .= "	script \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n";
3472
		$dhcp6cconf .= "};\n";
3473
	} else {
3474 6dcbd1b3 smos
		/* skip address request if this is set */
3475
		if(!isset($wancfg['dhcp6prefixonly']))
3476
			$dhcp6cconf .= "        send ia-na 0;   # request stateful address\n";
3477 b0059636 Ermal
		if(is_numeric($wancfg['dhcp6-ia-pd-len']))
3478 d53a9a51 smos
			$dhcp6cconf .= "	send ia-pd 0;	# request prefix delegation\n";
3479 6dcbd1b3 smos
3480
		$dhcp6cconf .= "\trequest domain-name-servers;\n";
3481
		$dhcp6cconf .= "\trequest domain-name;\n";
3482
		$dhcp6cconf .= "\tscript \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n";
3483 d53a9a51 smos
3484
		$dhcp6cconf .= "};\n";
3485 6dcbd1b3 smos
3486
		if(!isset($wancfg['dhcp6prefixonly']))
3487
			$dhcp6cconf .= "id-assoc na 0 { };\n";
3488
3489 d53a9a51 smos
		if(is_numeric($wancfg['dhcp6-ia-pd-len'])) {
3490
			/* Setup the prefix delegation */
3491
			$dhcp6cconf .= "id-assoc pd 0 {\n";
3492 7a04cd20 Ermal
			$iflist = link_interface_to_track6($interface);
3493
			foreach ($iflist as $friendly => $ifcfg) {
3494
				if (is_numeric($ifcfg['track6-prefix-id'])) {
3495
					if ($g['debug'])
3496
						log_error("setting up $ifdescr - {$ifcfg['track6-prefix-id']}");
3497 d53a9a51 smos
					$realif = get_real_interface($friendly);
3498
					$dhcp6cconf .= "	prefix-interface {$realif} {\n";
3499 7a04cd20 Ermal
					$dhcp6cconf .= "		sla-id {$ifcfg['track6-prefix-id']};\n";
3500 d53a9a51 smos
					$dhcp6cconf .= "		sla-len {$wancfg['dhcp6-ia-pd-len']};\n";
3501
					$dhcp6cconf .= "	};\n";
3502
				}
3503
			}
3504 7a04cd20 Ermal
			unset($iflist, $ifcfg);
3505 d53a9a51 smos
			$dhcp6cconf .= "};\n";
3506
		}
3507
	}
3508 b0059636 Ermal
	/* wide-dhcp6c works for now. */
3509
	if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}.conf", $dhcp6cconf)) {
3510
		printf("Error: cannot open dhcp6c_{$interface}.conf in interface_dhcpv6_configure() for writing.\n");
3511 d12ae241 Renato Botelho
		unset($dhcp6cconf);
3512 b0059636 Ermal
		return 1;
3513
	}
3514 d12ae241 Renato Botelho
	unset($dhcp6cconf);
3515 ed395640 Seth Mos
3516 b0059636 Ermal
	$dhcp6cscript = "#!/bin/sh\n";
3517
	$dhcp6cscript .= "# This shell script launches /etc/rc.newwanipv6 with a interface argument.\n";
3518
	$dhcp6cscript .= "/etc/rc.newwanipv6 {$wanif} \n";
3519 d53a9a51 smos
	/* Add wide-dhcp6c shell script here. Because we can not pass a argument to it. */
3520 b0059636 Ermal
	if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", $dhcp6cscript)) {
3521 d53a9a51 smos
		printf("Error: cannot open dhcp6c_{$interface}_script.sh in interface_dhcpv6_configure() for writing.\n");
3522 d12ae241 Renato Botelho
		unset($dhcp6cscript);
3523 d53a9a51 smos
		return 1;
3524
	}
3525 d12ae241 Renato Botelho
	unset($dhcp6cscript);
3526 b0059636 Ermal
	@chmod("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", 0755);
3527 d53a9a51 smos
3528 29f2f07a Ermal
	$rtsoldscript = "#!/bin/sh\n";
3529
	$rtsoldscript .= "# This shell script launches dhcp6c and configured gateways for this interface.\n";
3530
	$rtsoldscript .= "echo $2 > {$g['tmp_path']}/{$wanif}_routerv6\n";
3531
	$rtsoldscript .= "echo $2 > {$g['tmp_path']}/{$wanif}_defaultgwv6\n";
3532
	$rtsoldscript .= "if [ -f {$g['varrun_path']}/dhcp6c_{$wanif}.pid ]; then\n";
3533 b8ded125 Ermal
	$rtsoldscript .= "\t/bin/pkill -F {$g['varrun_path']}/dhcp6c_{$wanif}.pid\n";
3534 7fdd0c73 Ermal
	$rtsoldscript .= "\t/bin/sleep 1\n";
3535 29f2f07a Ermal
	$rtsoldscript .= "fi\n";
3536
	$rtsoldscript .= "/usr/local/sbin/dhcp6c -d -c {$g['varetc_path']}/dhcp6c_{$interface}.conf -p {$g['varrun_path']}/dhcp6c_{$wanif}.pid {$wanif}\n";
3537
	/* Add wide-dhcp6c shell script here. Because we can not pass a argument to it. */
3538
	if (!@file_put_contents("{$g['varetc_path']}/rtsold_{$wanif}_script.sh", $rtsoldscript)) {
3539
		printf("Error: cannot open rtsold_{$interface}_script.sh in interface_dhcpv6_configure() for writing.\n");
3540
		unset($rtsoldscript);
3541
		return 1;
3542
	}
3543
	unset($rtsoldscript);
3544
	@chmod("{$g['varetc_path']}/rtsold_{$wanif}_script.sh", 0755);
3545 d53a9a51 smos
3546 c65d3051 Seth Mos
	/* accept router advertisements for this interface */
3547 ef851fed smos
	mwexec("/sbin/sysctl -w net.inet6.ip6.accept_rtadv=1");
3548 49047fb4 smos
	log_error("Accept router advertisements on interface {$wanif} ");
3549 100c7be0 Seth Mos
	mwexec("/sbin/ifconfig {$wanif} inet6 accept_rtadv");
3550 61c4383d smos
3551 29f2f07a Ermal
	/* fire up rtsold for IPv6 RAs first, this backgrounds immediately. It will call dhcp6c */
3552 7fed35c8 Ermal
	if (isvalidpid("{$g['varrun_path']}/rtsold_{$wanif}.pid")) {
3553 29f2f07a Ermal
		killbypid("{$g['varrun_path']}/rtsold_{$wanif}.pid");
3554 7fed35c8 Ermal
		sleep(2);
3555
	}
3556 9b6010ff Ermal
	mwexec("/usr/sbin/rtsold -1 -p {$g['varrun_path']}/rtsold_{$wanif}.pid -O {$g['varetc_path']}/rtsold_{$wanif}_script.sh {$wanif}");
3557 82769dfe smos
3558 a8f5790a Renato Botelho
	/* NOTE: will be called from rtsold invoked script
3559 29f2f07a Ermal
	 * link_interface_to_track6($interface, "update");
3560
	 */
3561 b0059636 Ermal
3562 ed395640 Seth Mos
	return 0;
3563
}
3564
3565 8103bd1e Seth Mos
function interface_dhcp_configure($interface = "wan") {
3566 ed395640 Seth Mos
	global $config, $g;
3567
3568
	$wancfg = $config['interfaces'][$interface];
3569
	$wanif = $wancfg['if'];
3570 df9e93f0 Ermal
	if (empty($wancfg))
3571
		$wancfg = array();
3572 5b237745 Scott Ullrich
3573 0311dbd5 Scott Ullrich
	/* generate dhclient_wan.conf */
3574 67ee1ec5 Ermal Luçi
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
3575 5b237745 Scott Ullrich
	if (!$fd) {
3576 905ea336 Phil Davis
		printf(printf(gettext("Error: cannot open dhclient_%s.conf in interface_dhcp_configure() for writing.%s"), $interface, "\n"));
3577 5b237745 Scott Ullrich
		return 1;
3578
	}
3579 eb772abd Scott Ullrich
3580 2305d4c5 Scott Ullrich
	if ($wancfg['dhcphostname']) {
3581
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
3582
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
3583
	} else {
3584
		$dhclientconf_hostname = "";
3585
	}
3586
3587 85a5da13 Ermal Luçi
	$wanif = get_real_interface($interface);
3588 df9e93f0 Ermal
	if (empty($wanif)) {
3589 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("Invalid interface \"%s\" in interface_dhcp_configure()"), $interface));
3590 c1cc447c gnhb
		return 0;
3591 3a906378 gnhb
	}
3592 1c3ddd9e Renato Botelho
	$dhclientconf = "";
3593 be45aa79 Renato Botelho
3594 6d76590c Scott Ullrich
	$dhclientconf .= <<<EOD
3595 67ee1ec5 Ermal Luçi
interface "{$wanif}" {
3596 76d3b9a3 Chris Buechler
timeout 60;
3597 88810240 smos
retry 15;
3598 ce69a638 Scott Ullrich
select-timeout 0;
3599
initial-interval 1;
3600 2305d4c5 Scott Ullrich
	{$dhclientconf_hostname}
3601
	script "/sbin/dhclient-script";
3602 850324a2 jim-p
EOD;
3603
3604
if (is_ipaddrv4($wancfg['dhcprejectfrom'])) {
3605
	$dhclientconf .= <<<EOD
3606
3607
	reject {$wancfg['dhcprejectfrom']};
3608
EOD;
3609
}
3610
	$dhclientconf .= <<<EOD
3611
3612 5b237745 Scott Ullrich
}
3613
3614
EOD;
3615
3616 bc40d758 Seth Mos
if(is_ipaddr($wancfg['alias-address'])) {
3617
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
3618
	$dhclientconf .= <<<EOD
3619
alias {
3620 67ee1ec5 Ermal Luçi
	interface  "{$wanif}";
3621 bc40d758 Seth Mos
	fixed-address {$wancfg['alias-address']};
3622
	option subnet-mask {$subnetmask};
3623
}
3624
3625
EOD;
3626
}
3627 5b237745 Scott Ullrich
	fwrite($fd, $dhclientconf);
3628
	fclose($fd);
3629 eb772abd Scott Ullrich
3630 d7147b1c Scott Ullrich
	/* bring wan interface up before starting dhclient */
3631 3a906378 gnhb
	if($wanif)
3632
		interfaces_bring_up($wanif);
3633 be45aa79 Renato Botelho
	else
3634 07e40c1f Carlos Eduardo Ramos
		log_error(printf(gettext("Could not bring up %s interface in interface_dhcp_configure()"), $wanif));
3635 eacc8c14 Scott Ullrich
3636 7149c4e7 Seth Mos
	/* fire up dhclient */
3637 15d15c7f bcyrill
	mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif} > {$g['tmp_path']}/{$wanif}_output 2> {$g['tmp_path']}/{$wanif}_error_output");
3638 0119d2f7 Scott Ullrich
3639 5b237745 Scott Ullrich
	return 0;
3640
}
3641
3642 42753d25 Ermal Lu?i
function interfaces_group_setup() {
3643
	global $config;
3644
3645
	if (!is_array($config['ifgroups']['ifgroupentry']))
3646
		return;
3647
3648 482961e3 Ermal Lu?i
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
3649 42753d25 Ermal Lu?i
		interface_group_setup($groupar);
3650
3651
	return;
3652
}
3653
3654 abcb2bed Ermal Lu?i
function interface_group_setup(&$groupname /* The parameter is an array */) {
3655 42753d25 Ermal Lu?i
	global $config;
3656
3657
	if (!is_array($groupname))
3658
		return;
3659
	$members = explode(" ", $groupname['members']);
3660
	foreach($members as $ifs) {
3661
		$realif = get_real_interface($ifs);
3662
		if ($realif)
3663
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
3664
	}
3665
3666
	return;
3667
}
3668 48f23632 Ermal
3669 06182467 Renato Botelho
function is_interface_group($if) {
3670
	global $config;
3671
3672
	if (is_array($config['ifgroups']['ifgroupentry']))
3673
		foreach ($config['ifgroups']['ifgroupentry'] as $groupentry) {
3674
			if ($groupentry['ifname'] === $if)
3675
				return true;
3676
		}
3677
3678
	return false;
3679
}
3680
3681 48f23632 Ermal
function interface_group_add_member($interface, $groupname) {
3682 ed62880b Ermal
	$interface = get_real_interface($interface);
3683 48f23632 Ermal
	mwexec("/sbin/ifconfig {$interface} group {$groupname}", true);
3684
}
3685 be45aa79 Renato Botelho
3686 e8910ad4 Ermal Lu?i
/* COMPAT Function */
3687 afb2de1b Ermal Lu?i
function convert_friendly_interface_to_real_interface_name($interface) {
3688
	return get_real_interface($interface);
3689
}
3690
3691 e8910ad4 Ermal Lu?i
/* COMPAT Function */
3692 eba938e3 Scott Ullrich
function get_real_wan_interface($interface = "wan") {
3693 abb31ea4 Ermal Luçi
	return get_real_interface($interface);
3694
}
3695 afb2de1b Ermal Lu?i
3696 e8910ad4 Ermal Lu?i
/* COMPAT Function */
3697 eba938e3 Scott Ullrich
function get_current_wan_address($interface = "wan") {
3698 abb31ea4 Ermal Luçi
	return get_interface_ip($interface);
3699
}
3700
3701 afb2de1b Ermal Lu?i
/*
3702
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
3703
 */
3704
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
3705 7061ba0f Renato Botelho
	global $config;
3706 afb2de1b Ermal Lu?i
3707 7b47bd4c Ermal
	if (stristr($interface, "_vip")) {
3708 7061ba0f Renato Botelho
		foreach ($config['virtualip']['vip'] as $counter => $vip) {
3709
			if ($vip['mode'] == "carp")  {
3710
				if ($interface == "{$vip['interface']}_vip{$vip['vhid']}")
3711
					return $vip['interface'];
3712
			}
3713
		}
3714
	}
3715 afb2de1b Ermal Lu?i
3716 7061ba0f Renato Botelho
	/* XXX: For speed reasons reference directly the interface array */
3717 74e1e658 jim-p
	$ifdescrs = &$config['interfaces'];
3718 7061ba0f Renato Botelho
	//$ifdescrs = get_configured_interface_list(false, true);
3719 afb2de1b Ermal Lu?i
3720 7061ba0f Renato Botelho
	foreach ($ifdescrs as $if => $ifname) {
3721
		if ($if == $interface || $config['interfaces'][$if]['if'] == $interface)
3722
			return $if;
3723 afb2de1b Ermal Lu?i
3724 ca2b90ec Ermal
		if (get_real_interface($if) == $interface)
3725 7061ba0f Renato Botelho
			return $if;
3726 af637766 Erik Fonnesbeck
3727 d11e01f4 Erik Fonnesbeck
		// XXX: This case doesn't work anymore (segfaults - recursion?) - should be replaced with something else or just removed.
3728
		//      Not to be replaced with get_real_interface - causes slow interface listings here because of recursion!
3729
		/*
3730 7061ba0f Renato Botelho
		$int = get_parent_interface($if);
3731
		if ($int[0] == $interface)
3732
			return $ifname;
3733 a8f5790a Renato Botelho
		*/
3734 7061ba0f Renato Botelho
	}
3735 1d66a364 Ermal
3736 7061ba0f Renato Botelho
	return NULL;
3737 afb2de1b Ermal Lu?i
}
3738
3739
/* attempt to resolve interface to friendly descr */
3740
function convert_friendly_interface_to_friendly_descr($interface) {
3741 1c3ddd9e Renato Botelho
	global $config;
3742 afb2de1b Ermal Lu?i
3743 1c3ddd9e Renato Botelho
	switch ($interface) {
3744
	case "l2tp":
3745
		$ifdesc = "L2TP";
3746
		break;
3747 68ef6e03 Ermal
	case "pptp":
3748
		$ifdesc = "PPTP";
3749
		break;
3750
	case "pppoe":
3751
		$ifdesc = "PPPoE";
3752
		break;
3753
	case "openvpn":
3754
		$ifdesc = "OpenVPN";
3755
		break;
3756
	case "enc0":
3757
	case "ipsec":
3758
		$ifdesc = "IPsec";
3759
		break;
3760 1c3ddd9e Renato Botelho
	default:
3761
		if (isset($config['interfaces'][$interface])) {
3762
			if (empty($config['interfaces'][$interface]['descr']))
3763
				$ifdesc = strtoupper($interface);
3764
			else
3765
				$ifdesc = strtoupper($config['interfaces'][$interface]['descr']);
3766 57c52d45 Erik Fonnesbeck
			break;
3767 7b47bd4c Ermal
		} else if (stristr($interface, "_vip")) {
3768 68ef6e03 Ermal
			if (is_array($config['virtualip']['vip'])) {
3769
				foreach ($config['virtualip']['vip'] as $counter => $vip) {
3770 3e662cb0 Ermal
					if ($vip['mode'] == "carp")  {
3771 7b47bd4c Ermal
						if ($interface == "{$vip['interface']}_vip{$vip['vhid']}")
3772 68ef6e03 Ermal
							return "{$vip['subnet']} - {$vip['descr']}";
3773
					}
3774
				}
3775 1c3ddd9e Renato Botelho
			}
3776
		} else {
3777 68ef6e03 Ermal
			/* if list */
3778
			$ifdescrs = get_configured_interface_with_descr(false, true);
3779
			foreach ($ifdescrs as $if => $ifname) {
3780 7b47bd4c Ermal
				if ($if == $interface || $ifname == $interface)
3781
					return $ifname;
3782 68ef6e03 Ermal
			}
3783 57c52d45 Erik Fonnesbeck
		}
3784 1c3ddd9e Renato Botelho
		break;
3785
	}
3786 afb2de1b Ermal Lu?i
3787 1c3ddd9e Renato Botelho
	return $ifdesc;
3788 afb2de1b Ermal Lu?i
}
3789
3790
function convert_real_interface_to_friendly_descr($interface) {
3791 1c3ddd9e Renato Botelho
	global $config;
3792 afb2de1b Ermal Lu?i
3793 1c3ddd9e Renato Botelho
	$ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
3794 afb2de1b Ermal Lu?i
3795 1c3ddd9e Renato Botelho
	if ($ifdesc) {
3796
		$iflist = get_configured_interface_with_descr(false, true);
3797
		return $iflist[$ifdesc];
3798
	}
3799 afb2de1b Ermal Lu?i
3800 1c3ddd9e Renato Botelho
	return $interface;
3801 afb2de1b Ermal Lu?i
}
3802
3803 532b0fb8 Ermal Lu?i
/*
3804 d5dfcb52 gnhb
 *  get_parent_interface($interface):
3805 20cb9803 gnhb
 *			--returns the (real or virtual) parent interface(s) array for a given interface friendly name (i.e. wan)
3806
 *				or virtual interface (i.e. vlan)
3807
 *				(We need array because MLPPP and bridge interfaces have more than one parent.)
3808
 *			-- returns $interface passed in if $interface parent is not found
3809
 *			-- returns empty array if an invalid interface is passed
3810
 *	(Only handles ppps and vlans now.)
3811 532b0fb8 Ermal Lu?i
 */
3812 d5dfcb52 gnhb
function get_parent_interface($interface) {
3813
	global $config;
3814 532b0fb8 Ermal Lu?i
3815 20cb9803 gnhb
	$parents = array();
3816
	//Check that we got a valid interface passed
3817
	$realif = get_real_interface($interface);
3818
	if ($realif == NULL)
3819
		return $parents;
3820
3821
	// If we got a real interface, find it's friendly assigned name
3822
	$interface = convert_real_interface_to_friendly_interface_name($interface);
3823 be45aa79 Renato Botelho
3824 20cb9803 gnhb
	if (!empty($interface) && isset($config['interfaces'][$interface])) {
3825
		$ifcfg = $config['interfaces'][$interface];
3826
		switch ($ifcfg['ipaddr']) {
3827
			case "ppp":
3828
			case "pppoe":
3829
			case "pptp":
3830
			case "l2tp":
3831
				if (empty($parents))
3832
					if (is_array($config['ppps']['ppp']))
3833
						foreach ($config['ppps']['ppp'] as $pppidx => $ppp) {
3834 02b8bfae Renato Botelho
							if ($ifcfg['if'] == $ppp['if']) {
3835 20cb9803 gnhb
								$ports = explode(',', $ppp['ports']);
3836 be45aa79 Renato Botelho
								foreach ($ports as $pid => $parent_if)
3837 20cb9803 gnhb
									$parents[$pid] = get_real_interface($parent_if);
3838
								break;
3839
							}
3840
						}
3841
				break;
3842
			case "dhcp":
3843
			case "static":
3844
			default:
3845
				// Handle _vlans
3846 76254caa Renato Botelho
				if (stristr($realif,"_vlan"))
3847 be45aa79 Renato Botelho
					if (is_array($config['vlans']['vlan']))
3848 20cb9803 gnhb
						foreach ($config['vlans']['vlan'] as $vlanidx => $vlan)
3849
							if ($ifcfg['if'] == $vlan['vlanif']){
3850
								$parents[0] = $vlan['if'];
3851
								break;
3852
							}
3853
				break;
3854 3e5d0d1d Ermal
		}
3855
	}
3856 be45aa79 Renato Botelho
3857 20cb9803 gnhb
	if (empty($parents))
3858
		$parents[0] = $realif;
3859 be45aa79 Renato Botelho
3860 20cb9803 gnhb
	return $parents;
3861 532b0fb8 Ermal Lu?i
}
3862
3863 263e2b7e Erik Fonnesbeck
function interface_is_wireless_clone($wlif) {
3864
	if(!stristr($wlif, "_wlan")) {
3865
		return false;
3866
	} else {
3867
		return true;
3868
	}
3869
}
3870
3871 1d072761 Erik Fonnesbeck
function interface_get_wireless_base($wlif) {
3872 34808d4e Erik Fonnesbeck
	if(!stristr($wlif, "_wlan")) {
3873
		return $wlif;
3874
	} else {
3875
		return substr($wlif, 0, stripos($wlif, "_wlan"));
3876
	}
3877
}
3878
3879 1d072761 Erik Fonnesbeck
function interface_get_wireless_clone($wlif) {
3880 34808d4e Erik Fonnesbeck
	if(!stristr($wlif, "_wlan")) {
3881
		return $wlif . "_wlan0";
3882
	} else {
3883
		return $wlif;
3884
	}
3885
}
3886
3887 b6c1f22f Ermal
function get_real_interface($interface = "wan", $family = "all") {
3888 ee3576dd Ermal
	global $config, $g;
3889 cfc707f7 Scott Ullrich
3890 521cfa2f Ermal Lu?i
	$wanif = NULL;
3891 c515ea57 Scott Ullrich
3892 67ee1ec5 Ermal Luçi
	switch ($interface) {
3893 acc1e9d0 Scott Ullrich
	case "l2tp":
3894
		$wanif = "l2tp";
3895
		break;
3896 67ee1ec5 Ermal Luçi
	case "pptp":
3897
		$wanif = "pptp";
3898
		break;
3899
	case "pppoe":
3900
		$wanif = "pppoe";
3901
		break;
3902
	case "openvpn":
3903
		$wanif = "openvpn";
3904
		break;
3905 4563d12f Seth Mos
	case "ipsec":
3906 67ee1ec5 Ermal Luçi
	case "enc0":
3907
		$wanif = "enc0";
3908
		break;
3909
	case "ppp":
3910
		$wanif = "ppp";
3911
		break;
3912
	default:
3913 6d5446a2 Ermal
		// If a real interface was alread passed simply
3914
		// pass the real interface back.  This encourages
3915
		// the usage of this function in more cases so that
3916
		// we can combine logic for more flexibility.
3917
		if(does_interface_exist($interface)) {
3918
			$wanif = $interface;
3919
			break;
3920
		}
3921 bf001dec smos
3922 6d5446a2 Ermal
		if (empty($config['interfaces'][$interface]))
3923
			break;
3924 568b1358 Scott Ullrich
3925 6447bde5 jim-p
		$cfg = &$config['interfaces'][$interface];
3926 2ebf3945 Scott Ullrich
3927 b6c1f22f Ermal
		if ($family == "inet6") {
3928
			switch ($cfg['ipaddrv6']) {
3929
			case "6rd":
3930
			case "6to4":
3931
				$wanif = "{$interface}_stf";
3932
				break;
3933 4e69371b Ermal
			case 'pppoe':
3934
			case 'ppp':
3935
			case 'l2tp':
3936
			case 'pptp':
3937
				if( is_array($cfg['wireless']) || preg_match($g['wireless_regex'], $cfg['if']))
3938
					$wanif = interface_get_wireless_clone($cfg['if']);
3939
				else
3940
					$wanif = $cfg['if'];
3941
				break;
3942 b6c1f22f Ermal
			default:
3943 5128e0fe Ermal
				switch ($cfg['ipaddr']) {
3944
				case 'pppoe':
3945
				case 'ppp':
3946
				case 'l2tp':
3947
				case 'pptp':
3948 329024c8 Ermal
					if (isset($cfg['dhcp6usev4iface']))
3949 5128e0fe Ermal
						$wanif = $cfg['if'];
3950 329024c8 Ermal
					else {
3951
						$parents = get_parent_interface($interface);
3952
						if (!empty($parents[0]))
3953
							$wanif = $parents[0];
3954
						else
3955
							$wanif = $cfg['if'];
3956
					}
3957 5128e0fe Ermal
					break;
3958
				default:
3959
					if( is_array($cfg['wireless']) || preg_match($g['wireless_regex'], $cfg['if']))
3960
						$wanif = interface_get_wireless_clone($cfg['if']);
3961
					else
3962
						$wanif = $cfg['if'];
3963
					break;
3964
				}
3965 b6c1f22f Ermal
				break;
3966
			}
3967
		} else {
3968
			// Wireless cloned NIC support (FreeBSD 8+)
3969
			// interface name format: $parentnic_wlanparentnic#
3970
			// example: ath0_wlan0
3971
			if( is_array($cfg['wireless']) || preg_match($g['wireless_regex'], $cfg['if']))
3972
				$wanif = interface_get_wireless_clone($cfg['if']);
3973
			else
3974
				$wanif = $cfg['if'];
3975
		}
3976 67ee1ec5 Ermal Luçi
		break;
3977 c515ea57 Scott Ullrich
	}
3978
3979 1c3ddd9e Renato Botelho
	return $wanif;
3980 5b237745 Scott Ullrich
}
3981
3982 9ff8c299 Seth Mos
/* Guess the physical interface by providing a IP address */
3983 afb2de1b Ermal Lu?i
function guess_interface_from_ip($ipaddress) {
3984 80a2c1e6 Seth Mos
	if(! is_ipaddr($ipaddress)) {
3985 9ff8c299 Seth Mos
		return false;
3986
	}
3987 a05b2f42 Seth Mos
	if(is_ipaddrv4($ipaddress)) {
3988
		/* create a route table we can search */
3989
		exec("netstat -rnWf inet", $output, $ret);
3990
		foreach($output as $line) {
3991
			if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
3992
				$fields = preg_split("/[ ]+/", $line);
3993
				if(ip_in_subnet($ipaddress, $fields[0])) {
3994
					return $fields[6];
3995
				}
3996
			}
3997
		}
3998
	}
3999
	/* FIXME: This works from cursory testing, regexp might need fine tuning */
4000
	if(is_ipaddrv6($ipaddress)) {
4001
		/* create a route table we can search */
4002
		exec("netstat -rnWf inet6", $output, $ret);
4003
		foreach($output as $line) {
4004
			if(preg_match("/[0-9a-f]+[:]+[0-9a-f]+[:]+[\/][0-9]+/", $line)) {
4005
				$fields = preg_split("/[ ]+/", $line);
4006
				if(ip_in_subnet($ipaddress, $fields[0])) {
4007
					return $fields[6];
4008
				}
4009 9ff8c299 Seth Mos
			}
4010
		}
4011
	}
4012
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
4013
	if(empty($ret)) {
4014 1c3ddd9e Renato Botelho
		return false;
4015 9ff8c299 Seth Mos
	}
4016
	return $ret;
4017 afb2de1b Ermal Lu?i
}
4018
4019
/*
4020
 * find_ip_interface($ip): return the interface where an ip is defined
4021 59231855 Darren Embry
 *   (or if $bits is specified, where an IP within the subnet is defined)
4022 afb2de1b Ermal Lu?i
 */
4023 2027b4c7 bcyrill
function find_ip_interface($ip, $bits = null) {
4024
	if (!is_ipaddr($ip))
4025
		return false;
4026 a8f5790a Renato Botelho
4027 2027b4c7 bcyrill
	$isv6ip = is_ipaddrv6($ip);
4028 a8f5790a Renato Botelho
4029 59231855 Darren Embry
	/* if list */
4030
	$ifdescrs = get_configured_interface_list();
4031 be45aa79 Renato Botelho
4032 59231855 Darren Embry
	foreach ($ifdescrs as $ifdescr => $ifname) {
4033 2027b4c7 bcyrill
		$ifip = ($isv6ip) ? get_interface_ipv6($ifname) : get_interface_ip($ifname);
4034 ec8b4d8d Ermal
		if (is_null($ifip))
4035 2027b4c7 bcyrill
			continue;
4036 ec8b4d8d Ermal
		if (is_null($bits)) {
4037 2027b4c7 bcyrill
			if ($ip == $ifip) {
4038 59231855 Darren Embry
				$int = get_real_interface($ifname);
4039
				return $int;
4040
			}
4041
		}
4042
		else {
4043 2027b4c7 bcyrill
			if (ip_in_subnet($ifip, $ip . "/" . $bits)) {
4044 59231855 Darren Embry
				$int = get_real_interface($ifname);
4045
				return $int;
4046
			}
4047
		}
4048
	}
4049 ec8b4d8d Ermal
4050 59231855 Darren Embry
	return false;
4051
}
4052 afb2de1b Ermal Lu?i
4053 59231855 Darren Embry
/*
4054
 * find_virtual_ip_alias($ip): return the virtual IP alias where an IP is found
4055
 *   (or if $bits is specified, where an IP within the subnet is found)
4056
 */
4057
function find_virtual_ip_alias($ip, $bits = null) {
4058
	global $config;
4059 a8f5790a Renato Botelho
4060 59231855 Darren Embry
	if (!is_array($config['virtualip']['vip'])) {
4061
		return false;
4062
	}
4063 6b207f73 bcyrill
	if (!is_ipaddr($ip))
4064
		return false;
4065 a8f5790a Renato Botelho
4066 6b207f73 bcyrill
	$isv6ip = is_ipaddrv6($ip);
4067 a8f5790a Renato Botelho
4068 59231855 Darren Embry
	foreach ($config['virtualip']['vip'] as $vip) {
4069
		if ($vip['mode'] === "ipalias") {
4070 6b207f73 bcyrill
			if (is_ipaddrv6($vip['subnet']) != $isv6ip)
4071
				continue;
4072 ec8b4d8d Ermal
			if (is_null($bits)) {
4073 59231855 Darren Embry
				if (ip_in_subnet($ip, $vip['subnet'] . "/" . $vip['subnet_bits'])) {
4074
					return $vip;
4075
				}
4076
			}
4077
			else {
4078 dbea91b3 bcyrill
				if (($isv6ip && check_subnetsv6_overlap($ip, $bits, $vip['subnet'], $vip['subnet_bits']))
4079
					|| (!$isv6ip && check_subnets_overlap($ip, $bits, $vip['subnet'], $vip['subnet_bits']))) {
4080 59231855 Darren Embry
					return $vip;
4081
				}
4082
			}
4083 abcb2bed Ermal Lu?i
		}
4084 59231855 Darren Embry
	}
4085
	return false;
4086 afb2de1b Ermal Lu?i
}
4087
4088 a71b32d2 Scott Ullrich
/*
4089
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
4090
 */
4091
function find_number_of_created_carp_interfaces() {
4092
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
4093
}
4094
4095
function get_all_carp_interfaces() {
4096
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
4097 81c64284 Chris Buechler
	$ints = explode(" ", $ints);
4098 a71b32d2 Scott Ullrich
	return $ints;
4099
}
4100
4101 abcb2bed Ermal Lu?i
/*
4102
 * find_carp_interface($ip): return the carp interface where an ip is defined
4103
 */
4104
function find_carp_interface($ip) {
4105 27625b39 Scott Ullrich
	global $config;
4106 abcb2bed Ermal Lu?i
	if (is_array($config['virtualip']['vip'])) {
4107
		foreach ($config['virtualip']['vip'] as $vip) {
4108 3e662cb0 Ermal
			if ($vip['mode'] == "carp") {
4109 645ad665 Seth Mos
				if(is_ipaddrv4($ip)) {
4110
					$carp_ip = get_interface_ip($vip['interface']);
4111
				}
4112
				if(is_ipaddrv6($ip)) {
4113
					$carp_ip = get_interface_ipv6($vip['interface']);
4114
				}
4115
				exec("/sbin/ifconfig", $output, $return);
4116
				foreach($output as $line) {
4117
					$elements = preg_split("/[ ]+/i", $line);
4118
					if(strstr($elements[0], "vip"))
4119
						$curif = str_replace(":", "", $elements[0]);
4120
					if(stristr($line, $ip)) {
4121
						$if = $curif;
4122
						continue;
4123
					}
4124
				}
4125 a687f866 Namezero
4126 27625b39 Scott Ullrich
				if ($if)
4127
					return $if;
4128 abcb2bed Ermal Lu?i
			}
4129
		}
4130
	}
4131
}
4132
4133
function link_carp_interface_to_parent($interface) {
4134 6fb26a17 smos
	global $config;
4135 abcb2bed Ermal Lu?i
4136 6fb26a17 smos
	if ($interface == "")
4137
		return;
4138 abcb2bed Ermal Lu?i
4139 6fb26a17 smos
	$carp_ip = get_interface_ip($interface);
4140
	$carp_ipv6 = get_interface_ipv6($interface);
4141 abcb2bed Ermal Lu?i
4142 6fb26a17 smos
	if((!is_ipaddrv4($carp_ip)) && (!is_ipaddrv6($carp_ipv6)))
4143
		return;
4144 abcb2bed Ermal Lu?i
4145 6fb26a17 smos
	/* if list */
4146
	$ifdescrs = get_configured_interface_list();
4147
	foreach ($ifdescrs as $ifdescr => $ifname) {
4148
		/* check IPv4 */
4149
		if(is_ipaddrv4($carp_ip)) {
4150
			$interfaceip = get_interface_ip($ifname);
4151
			$subnet_bits = get_interface_subnet($ifname);
4152
			$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
4153
			if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
4154
				return $ifname;
4155
		}
4156
		/* Check IPv6 */
4157
		if(is_ipaddrv6($carp_ipv6)) {
4158
			$interfaceipv6 = get_interface_ipv6($ifname);
4159
			$prefixlen = get_interface_subnetv6($ifname);
4160
			if(ip_in_subnet($carp_ipv6, "{$interfaceipv6}/{$prefixlen}"))
4161
				return $ifname;
4162
		}
4163
	}
4164
	return "";
4165 abcb2bed Ermal Lu?i
}
4166
4167 6fb26a17 smos
4168 abcb2bed Ermal Lu?i
/****f* interfaces/link_ip_to_carp_interface
4169
 * NAME
4170
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
4171
 * INPUTS
4172
 *   $ip
4173
 * RESULT
4174
 *   $carp_ints
4175
 ******/
4176
function link_ip_to_carp_interface($ip) {
4177 1c3ddd9e Renato Botelho
	global $config;
4178 abcb2bed Ermal Lu?i
4179 1c3ddd9e Renato Botelho
	if (!is_ipaddr($ip))
4180
		return;
4181 abcb2bed Ermal Lu?i
4182 1c3ddd9e Renato Botelho
	$carp_ints = "";
4183
	if (is_array($config['virtualip']['vip'])) {
4184 1d002dc9 Ermal
		$first = 0;
4185 3fbc3487 Ermal
		$carp_int = array();
4186 1c3ddd9e Renato Botelho
		foreach ($config['virtualip']['vip'] as $vip) {
4187
			if ($vip['mode'] == "carp") {
4188
				$carp_ip = $vip['subnet'];
4189
				$carp_sn = $vip['subnet_bits'];
4190
				$carp_nw = gen_subnet($carp_ip, $carp_sn);
4191
				if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}")) {
4192 7b47bd4c Ermal
					$carp_int[] = "{$vip['interface']}_vip{$vip['vhid']}";
4193
				}
4194 1c3ddd9e Renato Botelho
			}
4195
		}
4196 3fbc3487 Ermal
		if (!empty($carp_int))
4197
			$carp_ints = implode(" ", array_unique($carp_int));
4198 1c3ddd9e Renato Botelho
	}
4199 abcb2bed Ermal Lu?i
4200 1c3ddd9e Renato Botelho
	return $carp_ints;
4201 abcb2bed Ermal Lu?i
}
4202
4203 7a04cd20 Ermal
function link_interface_to_track6($int, $action = "") {
4204
	global $config;
4205
4206
	if (empty($int))
4207
		return;
4208
4209
	if (is_array($config['interfaces'])) {
4210
		$list = array();
4211
		foreach ($config['interfaces'] as $ifname => $ifcfg) {
4212
			if (!isset($ifcfg['enable']))
4213
				continue;
4214
			if (!empty($ifcfg['ipaddrv6']) && $ifcfg['track6-interface'] == $int) {
4215
				if ($action == "update")
4216
					interface_track6_configure($ifname, $ifcfg);
4217
				else if ($action == "")
4218
					$list[$ifname] = $ifcfg;
4219
			}
4220
		}
4221
		return $list;
4222
	}
4223
}
4224
4225 7850de1c Ermal Lu?i
function link_interface_to_vlans($int, $action = "") {
4226
	global $config;
4227
4228
	if (empty($int))
4229
		return;
4230
4231
	if (is_array($config['vlans']['vlan'])) {
4232 a362a23a Ermal
		$ifaces = array();
4233 1c3ddd9e Renato Botelho
		foreach ($config['vlans']['vlan'] as $vlan) {
4234 fa4a331f Ermal
			if ($int == $vlan['if']) {
4235 7850de1c Ermal Lu?i
				if ($action == "update") {
4236 fa4a331f Ermal
					interfaces_bring_up($int);
4237 7850de1c Ermal Lu?i
				} else if ($action == "")
4238 a362a23a Ermal
					$ifaces[$vlan['tag']] = $vlan;
4239 7850de1c Ermal Lu?i
			}
4240
		}
4241 a362a23a Ermal
		if (!empty($ifaces))
4242
			return $ifaces;
4243 7850de1c Ermal Lu?i
	}
4244
}
4245
4246
function link_interface_to_vips($int, $action = "") {
4247 1c3ddd9e Renato Botelho
	global $config;
4248 e5ac67ed Ermal Lu?i
4249 1c3ddd9e Renato Botelho
	if (is_array($config['virtualip']['vip'])) {
4250 75201355 Ermal
		$result = array();
4251 dcadda55 Ermal
		foreach ($config['virtualip']['vip'] as $vip) {
4252
			if ($int == $vip['interface']) {
4253 7b47bd4c Ermal
				if ($action == "update")
4254
					interfaces_vips_configure($int);
4255
				else
4256 75201355 Ermal
					$result[] = $vip;
4257 7850de1c Ermal Lu?i
			}
4258 dcadda55 Ermal
		}
4259 75201355 Ermal
		return $result;
4260 dcadda55 Ermal
	}
4261 e5ac67ed Ermal Lu?i
}
4262
4263 afb2de1b Ermal Lu?i
/****f* interfaces/link_interface_to_bridge
4264
 * NAME
4265
 *   link_interface_to_bridge - Finds out a bridge group for an interface
4266
 * INPUTS
4267
 *   $ip
4268
 * RESULT
4269
 *   bridge[0-99]
4270
 ******/
4271
function link_interface_to_bridge($int) {
4272 1c3ddd9e Renato Botelho
	global $config;
4273 afb2de1b Ermal Lu?i
4274 1c3ddd9e Renato Botelho
	if (is_array($config['bridges']['bridged'])) {
4275
		foreach ($config['bridges']['bridged'] as $bridge) {
4276 a639bb91 Ermal
			if (in_array($int, explode(',', $bridge['members'])))
4277 1c3ddd9e Renato Botelho
				return "{$bridge['bridgeif']}";
4278 a639bb91 Ermal
		}
4279
	}
4280 afb2de1b Ermal Lu?i
}
4281
4282 48f23632 Ermal
function link_interface_to_group($int) {
4283 1c3ddd9e Renato Botelho
	global $config;
4284 48f23632 Ermal
4285 ed62880b Ermal
	$result = array();
4286
4287 1c3ddd9e Renato Botelho
	if (is_array($config['ifgroups']['ifgroupentry'])) {
4288
		foreach ($config['ifgroups']['ifgroupentry'] as $group) {
4289 1dbc0c43 Ermal
			if (in_array($int, explode(" ", $group['members'])))
4290 ed62880b Ermal
				$result[$group['ifname']] = $int;
4291 48f23632 Ermal
		}
4292
	}
4293 ed62880b Ermal
4294
	return $result;
4295 48f23632 Ermal
}
4296
4297 afb2de1b Ermal Lu?i
function link_interface_to_gre($interface) {
4298 1c3ddd9e Renato Botelho
	global $config;
4299 afb2de1b Ermal Lu?i
4300 ed62880b Ermal
	$result = array();
4301
4302 1c3ddd9e Renato Botelho
	if (is_array($config['gres']['gre'])) {
4303
		foreach ($config['gres']['gre'] as $gre)
4304
			if($gre['if'] == $interface)
4305 ed62880b Ermal
				$result[] = $gre;
4306
	}
4307
4308
	return $result;
4309 afb2de1b Ermal Lu?i
}
4310
4311
function link_interface_to_gif($interface) {
4312 1c3ddd9e Renato Botelho
	global $config;
4313 afb2de1b Ermal Lu?i
4314 ed62880b Ermal
	$result = array();
4315
4316 1c3ddd9e Renato Botelho
	if (is_array($config['gifs']['gif'])) {
4317
		foreach ($config['gifs']['gif'] as $gif)
4318
			if($gif['if'] == $interface)
4319
				$result[] = $gif;
4320 ed62880b Ermal
	}
4321
4322
	return $result;
4323 afb2de1b Ermal Lu?i
}
4324
4325
/*
4326
 * find_interface_ip($interface): return the interface ip (first found)
4327
 */
4328 a8f5790a Renato Botelho
function find_interface_ip($interface, $flush = false) {
4329 afb2de1b Ermal Lu?i
	global $interface_ip_arr_cache;
4330 01f1b601 Ermal
	global $interface_sn_arr_cache;
4331 afb2de1b Ermal Lu?i
4332
	$interface = str_replace("\n", "", $interface);
4333 be45aa79 Renato Botelho
4334 8256f324 gnhb
	if (!does_interface_exist($interface))
4335 afb2de1b Ermal Lu?i
		return;
4336
4337
	/* Setup IP cache */
4338
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
4339 3f70e618 Ermal Lu?i
		$ifinfo = pfSense_get_interface_addresses($interface);
4340
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
4341 01f1b601 Ermal
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
4342 afb2de1b Ermal Lu?i
	}
4343
4344
	return $interface_ip_arr_cache[$interface];
4345
}
4346
4347 47593ac6 Seth Mos
/*
4348
 * find_interface_ipv6($interface): return the interface ip (first found)
4349
 */
4350 a8f5790a Renato Botelho
function find_interface_ipv6($interface, $flush = false) {
4351 47593ac6 Seth Mos
	global $interface_ipv6_arr_cache;
4352
	global $interface_snv6_arr_cache;
4353 31ace4ea Seth Mos
	global $config;
4354 be45aa79 Renato Botelho
4355 31bdb9e5 smos
	$interface = trim($interface);
4356
	$interface = get_real_interface($interface);
4357 be45aa79 Renato Botelho
4358 47593ac6 Seth Mos
	if (!does_interface_exist($interface))
4359
		return;
4360
4361
	/* Setup IP cache */
4362
	if (!isset($interface_ipv6_arr_cache[$interface]) or $flush) {
4363 ed7edf07 Ermal
		$ifinfo = pfSense_get_interface_addresses($interface);
4364
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddr6'];
4365
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbits6'];
4366 47593ac6 Seth Mos
	}
4367
4368
	return $interface_ipv6_arr_cache[$interface];
4369
}
4370
4371 81a3b6f5 smos
/*
4372
 * find_interface_ipv6_ll($interface): return the interface ipv6 link local (first found)
4373
 */
4374 a8f5790a Renato Botelho
function find_interface_ipv6_ll($interface, $flush = false) {
4375 58418355 smos
	global $interface_llv6_arr_cache;
4376 81a3b6f5 smos
	global $config;
4377 be45aa79 Renato Botelho
4378 81a3b6f5 smos
	$interface = str_replace("\n", "", $interface);
4379 be45aa79 Renato Botelho
4380 81a3b6f5 smos
	if (!does_interface_exist($interface))
4381
		return;
4382
4383
	/* Setup IP cache */
4384 58418355 smos
	if (!isset($interface_llv6_arr_cache[$interface]) or $flush) {
4385 ed7edf07 Ermal
		$ifinfo = pfSense_getall_interface_addresses($interface);
4386
		foreach($ifinfo as $line) {
4387
			if (strstr($line, ":")) {
4388
				$parts = explode("/", $line);
4389
				if(is_linklocal($parts[0])) {
4390
					$ifinfo['linklocal'] = $parts[0];
4391 81a3b6f5 smos
				}
4392
			}
4393
		}
4394 58418355 smos
		$interface_llv6_arr_cache[$interface] = $ifinfo['linklocal'];
4395 81a3b6f5 smos
	}
4396 58418355 smos
	return $interface_llv6_arr_cache[$interface];
4397 81a3b6f5 smos
}
4398
4399 a8f5790a Renato Botelho
function find_interface_subnet($interface, $flush = false) {
4400 afb2de1b Ermal Lu?i
	global $interface_sn_arr_cache;
4401 01f1b601 Ermal
	global $interface_ip_arr_cache;
4402 afb2de1b Ermal Lu?i
4403
	$interface = str_replace("\n", "", $interface);
4404
	if (does_interface_exist($interface) == false)
4405
		return;
4406
4407
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
4408 bd96e1fe Ermal Lu?i
		$ifinfo = pfSense_get_interface_addresses($interface);
4409 01f1b601 Ermal
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
4410 bd96e1fe Ermal Lu?i
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
4411 1c3ddd9e Renato Botelho
	}
4412 afb2de1b Ermal Lu?i
4413
	return $interface_sn_arr_cache[$interface];
4414
}
4415
4416 a8f5790a Renato Botelho
function find_interface_subnetv6($interface, $flush = false) {
4417 47593ac6 Seth Mos
	global $interface_snv6_arr_cache;
4418
	global $interface_ipv6_arr_cache;
4419
4420
	$interface = str_replace("\n", "", $interface);
4421
	if (does_interface_exist($interface) == false)
4422
		return;
4423
4424
	if (!isset($interface_snv6_arr_cache[$interface]) or $flush) {
4425 f7496377 Ermal
		$ifinfo = pfSense_get_interface_addresses($interface);
4426
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddr6'];
4427
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbits6'];
4428 1c3ddd9e Renato Botelho
	}
4429 47593ac6 Seth Mos
4430
	return $interface_snv6_arr_cache[$interface];
4431
}
4432
4433 e19b7d1e Ermal
function ip_in_interface_alias_subnet($interface, $ipalias) {
4434
	global $config;
4435
4436
	if (empty($interface) || !is_ipaddr($ipalias))
4437 e8471084 Ermal
		return false;
4438 e19b7d1e Ermal
	if (is_array($config['virtualip']['vip'])) {
4439 1c3ddd9e Renato Botelho
		foreach ($config['virtualip']['vip'] as $vip) {
4440
			switch ($vip['mode']) {
4441
			case "ipalias":
4442
				if ($vip['interface'] <> $interface)
4443
					break;
4444 8e088ea5 jim-p
				$subnet = is_ipaddrv6($ipalias) ? gen_subnetv6($vip['subnet'], $vip['subnet_bits']) : gen_subnet($vip['subnet'], $vip['subnet_bits']);
4445
				if (ip_in_subnet($ipalias, $subnet . "/" . $vip['subnet_bits']))
4446 e8471084 Ermal
					return true;
4447 1c3ddd9e Renato Botelho
				break;
4448
			}
4449
		}
4450 e19b7d1e Ermal
	}
4451 e8471084 Ermal
4452
	return false;
4453 e19b7d1e Ermal
}
4454
4455 a8f5790a Renato Botelho
function get_interface_ip($interface = "wan") {
4456 bf001dec smos
	$realif = get_failover_interface($interface);
4457 afb2de1b Ermal Lu?i
	if (!$realif) {
4458
		if (preg_match("/^carp/i", $interface))
4459
			$realif = $interface;
4460 5a61fd69 smos
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4461 564df7c2 Ermal Lu?i
			$realif = $interface;
4462 afb2de1b Ermal Lu?i
		else
4463
			return null;
4464
	}
4465
4466 5e041d5f Scott Ullrich
	$curip = find_interface_ip($realif);
4467
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
4468
		return $curip;
4469 8256f324 gnhb
	else
4470
		return null;
4471 5b237745 Scott Ullrich
}
4472
4473 a8f5790a Renato Botelho
function get_interface_ipv6($interface = "wan", $flush = false) {
4474 479f0fda smos
	global $config;
4475 c4fc2eae Ermal
4476 909de400 Ermal
	$realif = get_failover_interface($interface, "inet6");
4477 47593ac6 Seth Mos
	if (!$realif) {
4478 c4fc2eae Ermal
		if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4479 47593ac6 Seth Mos
			$realif = $interface;
4480
		else
4481
			return null;
4482
	}
4483
4484 b6c1f22f Ermal
	$curip = find_interface_ipv6($realif, $flush);
4485 47593ac6 Seth Mos
	if ($curip && is_ipaddrv6($curip) && ($curip != "::"))
4486
		return $curip;
4487
	else
4488
		return null;
4489
}
4490
4491 a8f5790a Renato Botelho
function get_interface_linklocal($interface = "wan") {
4492 10054843 Ermal
4493
	$realif = get_failover_interface($interface, "inet6");
4494 58418355 smos
	if (!$realif) {
4495
		if (preg_match("/^carp/i", $interface))
4496
			$realif = $interface;
4497 5a61fd69 smos
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4498 58418355 smos
			$realif = $interface;
4499
		else
4500
			return null;
4501
	}
4502
4503
	$curip = find_interface_ipv6_ll($realif);
4504
	if ($curip && is_ipaddrv6($curip) && ($curip != "::"))
4505
		return $curip;
4506
	else
4507
		return null;
4508
}
4509
4510 a8f5790a Renato Botelho
function get_interface_subnet($interface = "wan") {
4511 31b24870 Ermal Luçi
	$realif = get_real_interface($interface);
4512 e88fbe50 Ermal Lu?i
	if (!$realif) {
4513 1c3ddd9e Renato Botelho
		if (preg_match("/^carp/i", $interface))
4514
			$realif = $interface;
4515
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4516
			$realif = $interface;
4517
		else
4518
			return null;
4519
	}
4520 e88fbe50 Ermal Lu?i
4521 5e041d5f Scott Ullrich
	$cursn = find_interface_subnet($realif);
4522
	if (!empty($cursn))
4523 31b24870 Ermal Luçi
		return $cursn;
4524
4525
	return null;
4526
}
4527
4528 a8f5790a Renato Botelho
function get_interface_subnetv6($interface = "wan") {
4529 c4fc2eae Ermal
	global $config;
4530
4531 6fb66736 Ermal
	$realif = get_real_interface($interface, "inet6");
4532 47593ac6 Seth Mos
	if (!$realif) {
4533 c4fc2eae Ermal
		if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4534 1c3ddd9e Renato Botelho
			$realif = $interface;
4535
		else
4536
			return null;
4537
	}
4538 47593ac6 Seth Mos
4539
	$cursn = find_interface_subnetv6($realif);
4540
	if (!empty($cursn))
4541
		return $cursn;
4542
4543
	return null;
4544
}
4545
4546 52947718 Ermal Lu?i
/* return outside interfaces with a gateway */
4547
function get_interfaces_with_gateway() {
4548 77ccab82 Scott Ullrich
	global $config;
4549 52947718 Ermal Lu?i
4550
	$ints = array();
4551
4552
	/* loop interfaces, check config for outbound */
4553 77ccab82 Scott Ullrich
	foreach($config['interfaces'] as $ifdescr => $ifname) {
4554
		switch ($ifname['ipaddr']) {
4555
			case "dhcp":
4556 39f750b5 gnhb
			case "ppp";
4557 77ccab82 Scott Ullrich
			case "pppoe":
4558
			case "pptp":
4559 6d5446a2 Ermal
			case "l2tp":
4560 9ebe7028 gnhb
			case "ppp";
4561 6d5446a2 Ermal
				$ints[$ifdescr] = $ifdescr;
4562 77ccab82 Scott Ullrich
			break;
4563
			default:
4564 c822154c jim-p
				if (substr($ifname['if'], 0, 4) ==  "ovpn" ||
4565 f6b30142 Ermal
				    !empty($ifname['gateway']))
4566 6d5446a2 Ermal
					$ints[$ifdescr] = $ifdescr;
4567 77ccab82 Scott Ullrich
			break;
4568
		}
4569
	}
4570
	return $ints;
4571 52947718 Ermal Lu?i
}
4572
4573
/* return true if interface has a gateway */
4574
function interface_has_gateway($friendly) {
4575 6d5446a2 Ermal
	global $config;
4576 52947718 Ermal Lu?i
4577 6d5446a2 Ermal
	if (!empty($config['interfaces'][$friendly])) {
4578 43a22ee2 jim-p
		$ifname = &$config['interfaces'][$friendly];
4579 6d5446a2 Ermal
		switch ($ifname['ipaddr']) {
4580
			case "dhcp":
4581
			case "pppoe":
4582
			case "pptp":
4583
			case "l2tp":
4584
			case "ppp";
4585
				return true;
4586
			break;
4587
			default:
4588 c822154c jim-p
				if (substr($ifname['if'], 0, 4) ==  "ovpn")
4589 e9d7afeb Ermal
					return true;
4590 6d5446a2 Ermal
				if (!empty($ifname['gateway']))
4591
					return true;
4592
			break;
4593
		}
4594
	}
4595 52947718 Ermal Lu?i
4596
	return false;
4597
}
4598
4599 2feb85af Seth Mos
/* return true if interface has a gateway */
4600
function interface_has_gatewayv6($friendly) {
4601
	global $config;
4602
4603
	if (!empty($config['interfaces'][$friendly])) {
4604
		$ifname = &$config['interfaces'][$friendly];
4605
		switch ($ifname['ipaddrv6']) {
4606 67102344 smos
			case "slaac":
4607 2feb85af Seth Mos
			case "dhcp6":
4608 a11a839d smos
			case "6to4":
4609 d500e296 smos
			case "6rd":
4610
				return true;
4611 a11a839d smos
				break;
4612 2feb85af Seth Mos
			default:
4613 c822154c jim-p
				if (substr($ifname['if'], 0, 4) ==  "ovpn")
4614 2feb85af Seth Mos
					return true;
4615
				if (!empty($ifname['gatewayv6']))
4616
					return true;
4617 a11a839d smos
				break;
4618 2feb85af Seth Mos
		}
4619
	}
4620
4621
	return false;
4622
}
4623
4624 a57b119e Bill Marquette
/****f* interfaces/is_altq_capable
4625
 * NAME
4626
 *   is_altq_capable - Test if interface is capable of using ALTQ
4627
 * INPUTS
4628
 *   $int            - string containing interface name
4629
 * RESULT
4630
 *   boolean         - true or false
4631
 ******/
4632
4633 eba938e3 Scott Ullrich
function is_altq_capable($int) {
4634 1c3ddd9e Renato Botelho
	/* Per:
4635
	 * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
4636
	 * Only the following drivers have ALTQ support
4637
	 */
4638 c2d7074e Ermal
	$capable = array("age", "alc", "ale", "an", "ath", "aue", "awi", "bce",
4639 a5ccf623 jim-p
			"bfe", "bge", "bridge", "cas", "dc", "de", "ed", "em", "ep", "fxp", "gem",
4640 be888d7f Ermal
			"hme", "igb", "ipw", "iwi", "jme", "le", "lem", "msk", "mxge", "my", "nfe",
4641 8c62fa48 jim-p
			"npe", "nve", "ral", "re", "rl", "rum", "run", "bwn", "sf", "sis", "sk",
4642 64fe3233 Seth Mos
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
4643 febca7e8 Ermal
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng",
4644 cf205dca Ermal
			"l2tp", "ppp", "vtnet");
4645 a57b119e Bill Marquette
4646 2ccac125 Renato Botelho
	$int_family = remove_ifindex($int);
4647 a57b119e Bill Marquette
4648 2163ace9 phildd
	if (in_array($int_family, $capable))
4649 1c3ddd9e Renato Botelho
		return true;
4650 dbe67167 Ermal
	else if (stristr($int, "l2tp")) /* VLANs are name $parent_$vlan now */
4651
		return true;
4652 76254caa Renato Botelho
	else if (stristr($int, "_vlan")) /* VLANs are name $parent_$vlan now */
4653 7e627719 Ermal
		return true;
4654 21699e76 Ermal
	else if (stristr($int, "_wlan")) /* WLANs are name $parent_$wlan now */
4655 2f3446db Ermal Lu?i
		return true;
4656 1c3ddd9e Renato Botelho
	else
4657
		return false;
4658 a57b119e Bill Marquette
}
4659
4660 52947718 Ermal Lu?i
/****f* interfaces/is_interface_wireless
4661
 * NAME
4662
 *   is_interface_wireless - Returns if an interface is wireless
4663
 * RESULT
4664
 *   $tmp       - Returns if an interface is wireless
4665
 ******/
4666
function is_interface_wireless($interface) {
4667 1c3ddd9e Renato Botelho
	global $config, $g;
4668
4669
	$friendly = convert_real_interface_to_friendly_interface_name($interface);
4670
	if(!isset($config['interfaces'][$friendly]['wireless'])) {
4671
		if (preg_match($g['wireless_regex'], $interface)) {
4672
			if (isset($config['interfaces'][$friendly]))
4673
				$config['interfaces'][$friendly]['wireless'] = array();
4674
			return true;
4675
		}
4676
		return false;
4677
	} else
4678
		return true;
4679 52947718 Ermal Lu?i
}
4680
4681 eba938e3 Scott Ullrich
function get_wireless_modes($interface) {
4682 d8c67d69 Scott Ullrich
	/* return wireless modes and channels */
4683 92f7d37d Ermal Luçi
	$wireless_modes = array();
4684
4685 5357f386 Erik Fonnesbeck
	$cloned_interface = get_real_interface($interface);
4686 1b773d20 Ermal Lu?i
4687 5357f386 Erik Fonnesbeck
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
4688 1b773d20 Ermal Lu?i
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
4689
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
4690 1de74081 Ermal Lu?i
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
4691 d8c67d69 Scott Ullrich
4692 4b0e71db Scott Ullrich
		$interface_channels = "";
4693 d8c67d69 Scott Ullrich
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
4694
		$interface_channel_count = count($interface_channels);
4695
4696
		$c = 0;
4697 a8f5790a Renato Botelho
		while ($c < $interface_channel_count) {
4698 d8c67d69 Scott Ullrich
			$channel_line = explode(",", $interface_channels["$c"]);
4699
			$wireless_mode = trim($channel_line[0]);
4700
			$wireless_channel = trim($channel_line[1]);
4701 4066776d Scott Ullrich
			if(trim($wireless_mode) != "") {
4702
				/* if we only have 11g also set 11b channels */
4703
				if($wireless_mode == "11g") {
4704 1ae54336 Erik Fonnesbeck
					if(!isset($wireless_modes["11b"]))
4705
						$wireless_modes["11b"] = array();
4706 39c1349c Erik Fonnesbeck
				} else if($wireless_mode == "11g ht") {
4707 1ae54336 Erik Fonnesbeck
					if(!isset($wireless_modes["11b"]))
4708
						$wireless_modes["11b"] = array();
4709
					if(!isset($wireless_modes["11g"]))
4710
						$wireless_modes["11g"] = array();
4711 39c1349c Erik Fonnesbeck
					$wireless_mode = "11ng";
4712
				} else if($wireless_mode == "11a ht") {
4713 1ae54336 Erik Fonnesbeck
					if(!isset($wireless_modes["11a"]))
4714
						$wireless_modes["11a"] = array();
4715 39c1349c Erik Fonnesbeck
					$wireless_mode = "11na";
4716 4066776d Scott Ullrich
				}
4717
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
4718
			}
4719 d8c67d69 Scott Ullrich
			$c++;
4720
		}
4721
	}
4722 4066776d Scott Ullrich
	return($wireless_modes);
4723 d8c67d69 Scott Ullrich
}
4724
4725 f4094f0d Erik Fonnesbeck
/* return channel numbers, frequency, max txpower, and max regulation txpower */
4726
function get_wireless_channel_info($interface) {
4727
	$wireless_channels = array();
4728
4729 5357f386 Erik Fonnesbeck
	$cloned_interface = get_real_interface($interface);
4730 f4094f0d Erik Fonnesbeck
4731 5357f386 Erik Fonnesbeck
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
4732 f4094f0d Erik Fonnesbeck
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
4733
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
4734
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
4735
4736
		$interface_channels = "";
4737
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
4738
4739
		foreach ($interface_channels as $channel_line) {
4740
			$channel_line = explode(",", $channel_line);
4741
			if(!isset($wireless_channels[$channel_line[0]]))
4742
				$wireless_channels[$channel_line[0]] = $channel_line;
4743
		}
4744
	}
4745
	return($wireless_channels);
4746
}
4747
4748 52947718 Ermal Lu?i
/****f* interfaces/get_interface_mtu
4749
 * NAME
4750
 *   get_interface_mtu - Return the mtu of an interface
4751
 * RESULT
4752
 *   $tmp       - Returns the mtu of an interface
4753
 ******/
4754
function get_interface_mtu($interface) {
4755 1c3ddd9e Renato Botelho
	$mtu = pfSense_get_interface_addresses($interface);
4756
	return $mtu['mtu'];
4757 52947718 Ermal Lu?i
}
4758
4759 eba938e3 Scott Ullrich
function get_interface_mac($interface) {
4760 7d6076f3 Ermal Lu?i
4761 3f70e618 Ermal Lu?i
	$macinfo = pfSense_get_interface_addresses($interface);
4762
	return $macinfo["macaddr"];
4763 f2ba47f8 Ermal Lu?i
}
4764
4765
/****f* pfsense-utils/generate_random_mac_address
4766
 * NAME
4767
 *   generate_random_mac - generates a random mac address
4768
 * INPUTS
4769
 *   none
4770
 * RESULT
4771
 *   $mac - a random mac address
4772
 ******/
4773
function generate_random_mac_address() {
4774 1c3ddd9e Renato Botelho
	$mac = "02";
4775
	for($x=0; $x<5; $x++)
4776
		$mac .= ":" . dechex(rand(16, 255));
4777
	return $mac;
4778 53c82ef9 Scott Ullrich
}
4779 b7ec2b9e Scott Ullrich
4780 52947718 Ermal Lu?i
/****f* interfaces/is_jumbo_capable
4781
 * NAME
4782
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
4783
 * INPUTS
4784
 *   $int             - string containing interface name
4785
 * RESULT
4786
 *   boolean          - true or false
4787
 ******/
4788 47ee6926 Ermal
function is_jumbo_capable($iface) {
4789
	$iface = trim($iface);
4790
	$capable = pfSense_get_interface_addresses($iface);
4791 a687f866 Namezero
4792 1c3ddd9e Renato Botelho
	if (isset($capable['caps']['vlanmtu']))
4793
		return true;
4794 a687f866 Namezero
4795 47ee6926 Ermal
	return false;
4796 52947718 Ermal Lu?i
}
4797
4798 70e46e62 Ermal
function interface_setup_pppoe_reset_file($pppif, $iface="") {
4799 55f3ca1d gnhb
	global $g;
4800 70e46e62 Ermal
4801 5c8e8a17 gnhb
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
4802 766bd6d0 gnhb
4803 5c8e8a17 gnhb
	if(!empty($iface) && !empty($pppif)){
4804 7673cdb5 Ermal
		$cron_cmd = <<<EOD
4805
#!/bin/sh
4806
/usr/local/sbin/pfSctl -c 'interface reload {$iface}'
4807 70e46e62 Ermal
/usr/bin/logger -t {$pppif} "PPPoE periodic reset executed on {$iface}"
4808 7673cdb5 Ermal
4809
EOD;
4810
4811 70e46e62 Ermal
		@file_put_contents($cron_file, $cron_cmd);
4812
		chmod($cron_file, 0755);
4813 55f3ca1d gnhb
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
4814 a5d6f60b Ermal Lu?i
	} else
4815 766bd6d0 gnhb
		unlink_if_exists($cron_file);
4816 b7ec2b9e Scott Ullrich
}
4817
4818 56da23dc Ermal
function get_interface_default_mtu($type = "ethernet") {
4819
	switch ($type) {
4820
	case "gre":
4821
		return 1476;
4822
		break;
4823
	case "gif":
4824
		return 1280;
4825
		break;
4826
	case "tun":
4827
	case "vlan":
4828
	case "tap":
4829
	case "ethernet":
4830
	default:
4831
		return 1500;
4832
		break;
4833
	}
4834
4835
	/* Never reached */
4836
	return 1500;
4837
}
4838
4839 dd62256f Pierre POMES
function get_vip_descr($ipaddress) {
4840
	global $config;
4841
4842
	foreach ($config['virtualip']['vip'] as $vip) {
4843
		if ($vip['subnet'] == $ipaddress) {
4844
			return ($vip['descr']);
4845
		}
4846
	}
4847
	return "";
4848
}
4849
4850 d368b334 jim-p
function interfaces_staticarp_configure($if) {
4851
	global $config, $g;
4852
	if(isset($config['system']['developerspew'])) {
4853
		$mt = microtime();
4854
		echo "interfaces_staticarp_configure($if) being called $mt\n";
4855
	}
4856
4857
	$ifcfg = $config['interfaces'][$if];
4858
4859 873e49ec Renato Botelho
	if (empty($if) || empty($ifcfg['if']) || !isset($ifcfg['enable']))
4860 d368b334 jim-p
		return 0;
4861
4862
	/* Enable staticarp, if enabled */
4863
	if(isset($config['dhcpd'][$if]['staticarp'])) {
4864
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
4865
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
4866
		if (is_array($config['dhcpd'][$if]['staticmap'])) {
4867
4868
			foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
4869
				mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
4870
4871
			}
4872
4873
		}
4874
	} else {
4875
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
4876
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
4877 c06e4f69 Ermal
		if (is_array($config['dhcpd'][$if]) && is_array($config['dhcpd'][$if]['staticmap'])) {
4878 25c1ebd5 N0YB
			foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
4879
				if (isset($arpent['arp_table_static_entry'])) {
4880
					mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
4881
				}
4882
			}
4883
		}
4884 d368b334 jim-p
	}
4885
4886
	return 0;
4887
}
4888
4889 909de400 Ermal
function get_failover_interface($interface, $family = "all") {
4890 bf001dec smos
	global $config;
4891 10054843 Ermal
4892 e90c833a smos
	/* shortcut to get_real_interface if we find it in the config */
4893 10054843 Ermal
	if (is_array($config['interfaces'][$interface])) {
4894
		return get_real_interface($interface, $family);
4895 e90c833a smos
	}
4896
4897 bf001dec smos
	/* compare against gateway groups */
4898
	$a_groups = return_gateway_groups_array();
4899 10054843 Ermal
	if (is_array($a_groups[$interface])) {
4900 bf001dec smos
		/* we found a gateway group, fetch the interface or vip */
4901 10054843 Ermal
		if ($a_groups[$interface][0]['vip'] <> "")
4902
			return $a_groups[$interface][0]['vip'];
4903 bf001dec smos
		else
4904 10054843 Ermal
			return $a_groups[$interface][0]['int'];
4905 bf001dec smos
	}
4906
	/* fall through to get_real_interface */
4907 10054843 Ermal
	/* XXX: Really needed? */
4908
	return get_real_interface($interface, $family);
4909 bf001dec smos
}
4910
4911 2ccac125 Renato Botelho
function remove_ifindex($ifname) {
4912
	return preg_replace("/[0-9]+$/", "", $ifname);
4913
}
4914
4915 6a7dd9bb Ermal
?>