Project

General

Profile

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