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