Project

General

Profile

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