Project

General

Profile

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