Project

General

Profile

Download (173 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
 * Copyright (c) 2004-2016 Electric Sheep Fencing, LLC
7
 * 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 cf73302f Phil Davis
				if (!is_ipaddr($gateways[$pid])) {
1686 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));
1687 69c1b043 gnhb
					return 0;
1688 3a906378 gnhb
				}
1689 3d04de61 Ermal
				pfSense_ngctl_attach(".", $port);
1690 3a906378 gnhb
				break;
1691
			case "ppp":
1692
				if (!file_exists("{$port}")) {
1693 07e40c1f Carlos Eduardo Ramos
					log_error(sprintf(gettext("Device %s does not exist. PPP link cannot start without the modem device."), $port));
1694 23721285 gnhb
					return 0;
1695 3a906378 gnhb
				}
1696
				break;
1697
			default:
1698 f416763b Phil Davis
				log_error(sprintf(gettext("Unknown %s configured as ppp interface."), $type));
1699 3a906378 gnhb
				break;
1700
		}
1701
	}
1702 be45aa79 Renato Botelho
1703 cf73302f Phil Davis
	if (is_array($ports) && count($ports) > 1) {
1704 cb37d8fa gnhb
		$multilink = "enable";
1705 cf73302f Phil Davis
	} else {
1706 cb37d8fa gnhb
		$multilink = "disable";
1707 cf73302f Phil Davis
	}
1708 be45aa79 Renato Botelho
1709 cf73302f Phil Davis
	if ($type == "modem") {
1710
		if (is_ipaddr($ppp['localip'])) {
1711 cb37d8fa gnhb
			$localip = $ppp['localip'];
1712 cf73302f Phil Davis
		} else {
1713 cb37d8fa gnhb
			$localip = '0.0.0.0';
1714 cf73302f Phil Davis
		}
1715 cb37d8fa gnhb
1716 cf73302f Phil Davis
		if (is_ipaddr($ppp['gateway'])) {
1717 cb37d8fa gnhb
			$gateway = $ppp['gateway'];
1718 cf73302f Phil Davis
		} else {
1719 23721285 gnhb
			$gateway = "10.64.64.{$pppid}";
1720 cf73302f Phil Davis
		}
1721 cb37d8fa gnhb
		$ranges = "{$localip}/0 {$gateway}/0";
1722 be45aa79 Renato Botelho
1723 cf73302f Phil Davis
		if (empty($ppp['apnum'])) {
1724 3a906378 gnhb
			$ppp['apnum'] = 1;
1725 cf73302f Phil Davis
		}
1726
	} else {
1727 cb37d8fa gnhb
		$ranges = "0.0.0.0/0 0.0.0.0/0";
1728 cf73302f Phil Davis
	}
1729 0661b194 gnhb
1730 cf73302f Phil Davis
	if (isset($ppp['ondemand'])) {
1731 cb37d8fa gnhb
		$ondemand = "enable";
1732 cf73302f Phil Davis
	} else {
1733 cb37d8fa gnhb
		$ondemand = "disable";
1734 cf73302f Phil Davis
	}
1735
	if (!isset($ppp['idletimeout'])) {
1736 cb37d8fa gnhb
		$ppp['idletimeout'] = 0;
1737 cf73302f Phil Davis
	}
1738 64d124c5 gnhb
1739 cf73302f Phil Davis
	if (empty($ppp['username']) && $type == "modem") {
1740 cb37d8fa gnhb
		$ppp['username'] = "user";
1741
		$ppp['password'] = "none";
1742
	}
1743 cf73302f Phil Davis
	if (empty($ppp['password']) && $type == "modem") {
1744 00b702cc gnhb
		$passwd = "none";
1745 cf73302f Phil Davis
	} else {
1746 00b702cc gnhb
		$passwd = base64_decode($ppp['password']);
1747 cf73302f Phil Davis
	}
1748 0661b194 gnhb
1749 086cf944 Phil Davis
	$bandwidths = explode(',', $ppp['bandwidth']);
1750 6805d2d2 Ermal
	$defaultmtu = "1492";
1751 cf73302f Phil Davis
	if (!empty($ifcfg['mtu'])) {
1752 6805d2d2 Ermal
		$defaultmtu = intval($ifcfg['mtu']);
1753 cf73302f Phil Davis
	}
1754 89c8934f Luiz Otavio O Souza
	if (isset($ppp['mtu'])) {
1755
		$mtus = explode(',', $ppp['mtu']);
1756
	}
1757
	if (isset($ppp['mru'])) {
1758
		$mrus = explode(',', $ppp['mru']);
1759
	}
1760 cf73302f Phil Davis
	if (isset($ppp['mrru'])) {
1761 086cf944 Phil Davis
		$mrrus = explode(',', $ppp['mrru']);
1762 cf73302f Phil Davis
	}
1763 c1cc447c gnhb
1764 cb37d8fa gnhb
	// Construct the mpd.conf file
1765
	$mpdconf = <<<EOD
1766
startup:
1767
	# configure the console
1768
	set console close
1769
	# configure the web server
1770
	set web close
1771
1772
default:
1773
{$ppp['type']}client:
1774
	create bundle static {$interface}
1775 07dfd121 Seth Mos
	set bundle enable ipv6cp
1776 cb37d8fa gnhb
	set iface name {$pppif}
1777
1778
EOD;
1779 0661b194 gnhb
	$setdefaultgw = false;
1780
	$founddefaultgw = false;
1781
	if (is_array($config['gateways']['gateway_item'])) {
1782 cf73302f Phil Davis
		foreach ($config['gateways']['gateway_item'] as $gateway) {
1783
			if ($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
1784 0661b194 gnhb
				$setdefaultgw = true;
1785
				break;
1786
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
1787
				$founddefaultgw = true;
1788
				break;
1789
			}
1790
		}
1791
	}
1792 be45aa79 Renato Botelho
1793 2efb39d0 jim-p
/* Omit this, we maintain the default route by other means, and it causes problems with
1794 5bd2dd83 Chris Buechler
 * default gateway switching. See redmine #1837 for original issue
1795
 * re-enabling this for now to fix issue with missing default gateway with PPPoE in some 
1796
 * edge case. redmine #6495 open to address. 
1797
 */
1798 cf73302f Phil Davis
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true) {
1799 82effddb gnhb
		$setdefaultgw = true;
1800 cb37d8fa gnhb
		$mpdconf .= <<<EOD
1801
	set iface route default
1802
1803
EOD;
1804 82effddb gnhb
	}
1805 cb37d8fa gnhb
	$mpdconf .= <<<EOD
1806
	set iface {$ondemand} on-demand
1807
	set iface idle {$ppp['idletimeout']}
1808
1809
EOD;
1810
1811 cf73302f Phil Davis
	if (isset($ppp['ondemand'])) {
1812 cb37d8fa gnhb
		$mpdconf .= <<<EOD
1813 55f3ca1d gnhb
	set iface addrs 10.10.1.1 10.10.1.2
1814 cb37d8fa gnhb
1815
EOD;
1816 cf73302f Phil Davis
	}
1817 be45aa79 Renato Botelho
1818 cf73302f Phil Davis
	if (isset($ppp['tcpmssfix'])) {
1819 8adc1e49 gnhb
		$tcpmss = "disable";
1820 cf73302f Phil Davis
	} else {
1821 8adc1e49 gnhb
		$tcpmss = "enable";
1822 cf73302f Phil Davis
	}
1823
	$mpdconf .= <<<EOD
1824 8adc1e49 gnhb
	set iface {$tcpmss} tcpmssfix
1825 64d124c5 gnhb
1826
EOD;
1827 0661b194 gnhb
1828 cb37d8fa gnhb
	$mpdconf .= <<<EOD
1829
	set iface up-script /usr/local/sbin/ppp-linkup
1830
	set iface down-script /usr/local/sbin/ppp-linkdown
1831
	set ipcp ranges {$ranges}
1832
1833
EOD;
1834 cf73302f Phil Davis
	if (isset($ppp['vjcomp'])) {
1835 cb37d8fa gnhb
		$mpdconf .= <<<EOD
1836 64d124c5 gnhb
	set ipcp no vjcomp
1837 cb37d8fa gnhb
1838
EOD;
1839 cf73302f Phil Davis
	}
1840 cb37d8fa gnhb
1841 cf73302f Phil Davis
	if (isset($config['system']['dnsallowoverride'])) {
1842 64d124c5 gnhb
		$mpdconf .= <<<EOD
1843
	set ipcp enable req-pri-dns
1844
	set ipcp enable req-sec-dns
1845
1846
EOD;
1847 cf73302f Phil Davis
	}
1848
1849
	if (!isset($ppp['verbose_log'])) {
1850 23721285 gnhb
		$mpdconf .= <<<EOD
1851 5d9d443a gnhb
	#log -bund -ccp -chat -iface -ipcp -lcp -link
1852 0661b194 gnhb
1853 23721285 gnhb
EOD;
1854 cf73302f Phil Davis
	}
1855
1856
	foreach ($ports as $pid => $port) {
1857 bfbb9bc0 Ermal
		$port = get_real_interface($port);
1858 00b702cc gnhb
		$mpdconf .= <<<EOD
1859 cb37d8fa gnhb
1860 0661b194 gnhb
	create link static {$interface}_link{$pid} {$type}
1861 cb37d8fa gnhb
	set link action bundle {$interface}
1862
	set link {$multilink} multilink
1863
	set link keep-alive 10 60
1864
	set link max-redial 0
1865 64d124c5 gnhb
1866
EOD;
1867 cf73302f Phil Davis
		if (isset($ppp['shortseq'])) {
1868 00b702cc gnhb
			$mpdconf .= <<<EOD
1869 64d124c5 gnhb
	set link no shortseq
1870
1871
EOD;
1872 cf73302f Phil Davis
		}
1873 0661b194 gnhb
1874 cf73302f Phil Davis
		if (isset($ppp['acfcomp'])) {
1875 00b702cc gnhb
			$mpdconf .= <<<EOD
1876 64d124c5 gnhb
	set link no acfcomp
1877
1878
EOD;
1879 cf73302f Phil Davis
		}
1880 0661b194 gnhb
1881 cf73302f Phil Davis
		if (isset($ppp['protocomp'])) {
1882 00b702cc gnhb
			$mpdconf .= <<<EOD
1883 64d124c5 gnhb
	set link no protocomp
1884
1885
EOD;
1886 cf73302f Phil Davis
		}
1887 0661b194 gnhb
1888 00b702cc gnhb
		$mpdconf .= <<<EOD
1889 cb37d8fa gnhb
	set link disable chap pap
1890
	set link accept chap pap eap
1891 64d124c5 gnhb
	set link disable incoming
1892 cb37d8fa gnhb
1893
EOD;
1894 00b702cc gnhb
1895
1896 cf73302f Phil Davis
		if (!empty($bandwidths[$pid])) {
1897 00b702cc gnhb
			$mpdconf .= <<<EOD
1898
	set link bandwidth {$bandwidths[$pid]}
1899 cb37d8fa gnhb
1900
EOD;
1901 cf73302f Phil Davis
		}
1902 0661b194 gnhb
1903 cf73302f Phil Davis
		if (empty($mtus[$pid])) {
1904 6805d2d2 Ermal
			$mtus[$pid] = $defaultmtu;
1905 cf73302f Phil Davis
		}
1906 6a74d2d7 David Wood
		if ($type == "pppoe") {
1907
			if ($mtus[$pid] > (get_interface_mtu($port) - 8)) {
1908
				$mtus[$pid] = get_interface_mtu($port) - 8;
1909
			}
1910
		}
1911
		if (! ($type == "pppoe" && $mtus[$pid] > 1492) ) {
1912
			// N.B. MTU for PPPoE with MTU > 1492 is set using pppoe max-payload - see below
1913
			$mpdconf .= <<<EOD
1914 00b702cc gnhb
	set link mtu {$mtus[$pid]}
1915 cb37d8fa gnhb
1916
EOD;
1917 6a74d2d7 David Wood
		}
1918 0661b194 gnhb
1919 cf73302f Phil Davis
		if (!empty($mrus[$pid])) {
1920 00b702cc gnhb
			$mpdconf .= <<<EOD
1921
	set link mru {$mrus[$pid]}
1922
1923 6a30f701 gnhb
EOD;
1924 cf73302f Phil Davis
		}
1925 6a30f701 gnhb
1926 cf73302f Phil Davis
		if (!empty($mrrus[$pid])) {
1927 6a30f701 gnhb
			$mpdconf .= <<<EOD
1928
	set link mrru {$mrrus[$pid]}
1929
1930 00b702cc gnhb
EOD;
1931 cf73302f Phil Davis
		}
1932 0661b194 gnhb
1933 00b702cc gnhb
		$mpdconf .= <<<EOD
1934 cb37d8fa gnhb
	set auth authname "{$ppp['username']}"
1935
	set auth password {$passwd}
1936
1937
EOD;
1938 00b702cc gnhb
		if ($type == "modem") {
1939
			$mpdconf .= <<<EOD
1940 cb37d8fa gnhb
	set modem device {$ppp['ports']}
1941
	set modem script DialPeer
1942 73472985 Ermal
	set modem idle-script Ringback
1943 cb37d8fa gnhb
	set modem watch -cd
1944
	set modem var \$DialPrefix "DT"
1945
	set modem var \$Telephone "{$ppp['phone']}"
1946
1947
EOD;
1948 00b702cc gnhb
		}
1949
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1950
			$mpdconf .= <<<EOD
1951 cb37d8fa gnhb
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1952
1953
EOD;
1954 00b702cc gnhb
		}
1955
		if (isset($ppp['initstr']) && $type == "modem") {
1956
			$initstr = base64_decode($ppp['initstr']);
1957
			$mpdconf .= <<<EOD
1958 cb37d8fa gnhb
	set modem var \$InitString "{$initstr}"
1959
1960
EOD;
1961 00b702cc gnhb
		}
1962
		if (isset($ppp['simpin']) && $type == "modem") {
1963 cf73302f Phil Davis
			if ($ppp['pin-wait'] == "") {
1964 2a210730 smos
				$ppp['pin-wait'] = 0;
1965 cf73302f Phil Davis
			}
1966 00b702cc gnhb
			$mpdconf .= <<<EOD
1967 cb37d8fa gnhb
	set modem var \$SimPin "{$ppp['simpin']}"
1968
	set modem var \$PinWait "{$ppp['pin-wait']}"
1969
1970
EOD;
1971 00b702cc gnhb
		}
1972
		if (isset($ppp['apn']) && $type == "modem") {
1973
			$mpdconf .= <<<EOD
1974 cb37d8fa gnhb
	set modem var \$APN "{$ppp['apn']}"
1975
	set modem var \$APNum "{$ppp['apnum']}"
1976
1977
EOD;
1978 00b702cc gnhb
		}
1979 233e2af1 jim-p
		if ($type == "pppoe") {
1980
			// Send a null service name if none is set.
1981
			$provider = isset($ppp['provider']) ? $ppp['provider'] : "";
1982 00b702cc gnhb
			$mpdconf .= <<<EOD
1983 233e2af1 jim-p
	set pppoe service "{$provider}"
1984 cb37d8fa gnhb
1985 6a74d2d7 David Wood
EOD;
1986
		}
1987
		if ($type == "pppoe" && $mtus[$pid] > 1492) {
1988
			$mpdconf .= <<<EOD
1989
	set pppoe max-payload {$mtus[$pid]}
1990
1991 cb37d8fa gnhb
EOD;
1992 00b702cc gnhb
		}
1993 cf73302f Phil Davis
		if ($type == "pppoe") {
1994 00b702cc gnhb
			$mpdconf .= <<<EOD
1995 64d124c5 gnhb
	set pppoe iface {$port}
1996 cb37d8fa gnhb
1997
EOD;
1998 cf73302f Phil Davis
		}
1999 0661b194 gnhb
2000 39f750b5 gnhb
		if ($type == "pptp" || $type == "l2tp") {
2001 00b702cc gnhb
			$mpdconf .= <<<EOD
2002 18ec0f13 Ermal
	set {$type} self {$localips[$pid]}
2003
	set {$type} peer {$gateways[$pid]}
2004 cb37d8fa gnhb
2005
EOD;
2006 00b702cc gnhb
		}
2007 be45aa79 Renato Botelho
2008 04f357bc Ermal
		$mpdconf .= "\topen\n";
2009 cf73302f Phil Davis
	} //end foreach ($port)
2010 cb37d8fa gnhb
2011 df309b37 gnhb
2012
	/* Generate mpd.conf. If mpd_[interface].conf exists in the conf path, then link to it instead of generating a fresh conf file. */
2013 cf73302f Phil Davis
	if (file_exists("{$g['conf_path']}/mpd_{$interface}.conf")) {
2014 80d708de Renato Botelho
		@symlink("{$g['conf_path']}/mpd_{$interface}.conf", "{$g['varetc_path']}/mpd_{$interface}.conf");
2015 cf73302f Phil Davis
	} else {
2016 df309b37 gnhb
		$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
2017
		if (!$fd) {
2018 d18f3f6e Phil Davis
			log_error(sprintf(gettext('Error: cannot open mpd_%1$s.conf in interface_ppps_configure().%2$s'), $interface, "\n"));
2019 df309b37 gnhb
			return 0;
2020
		}
2021
		// Write out mpd_ppp.conf
2022
		fwrite($fd, $mpdconf);
2023
		fclose($fd);
2024 14d079b3 Ermal
		unset($mpdconf);
2025 df309b37 gnhb
	}
2026 cb37d8fa gnhb
2027
	// Create the uptime log if requested and if it doesn't exist already, or delete it if it is no longer requested.
2028
	if (isset($ppp['uptime'])) {
2029
		if (!file_exists("/conf/{$pppif}.log")) {
2030
			conf_mount_rw();
2031 873c1701 Renato Botelho
			file_put_contents("/conf/{$pppif}.log", '');
2032 cb37d8fa gnhb
			conf_mount_ro();
2033
		}
2034
	} else {
2035
		if (file_exists("/conf/{$pppif}.log")) {
2036
			conf_mount_rw();
2037 552f5a6a Renato Botelho
			@unlink("/conf/{$pppif}.log");
2038 cb37d8fa gnhb
			conf_mount_ro();
2039
		}
2040
	}
2041 92a1c8e6 Ermal
2042 7e631290 smos
	/* clean up old lock files */
2043 cf73302f Phil Davis
	foreach ($ports as $port) {
2044
		if (file_exists("{$g['var_path']}/spool/lock/LCK..{$port}")) {
2045 17d656fc smos
			unlink("{$g['var_path']}/spool/lock/LCK..{$port}");
2046 cf73302f Phil Davis
		}
2047 7e631290 smos
	}
2048
2049 0c9b98c0 Chris Buechler
	/* Set temporary bogon (RFC 5737) IPv4 addresses to work round mpd5 IPv6CP issue causing */
2050
	/* random IPv6 interface identifier during boot. More details at */
2051
	/* https://forum.pfsense.org/index.php?topic=101967.msg570519#msg570519 */
2052
	if (platform_booting() && is_array($config['interfaces'])) {
2053
		$count = 0;
2054
		foreach ($config['interfaces'] as $tempifacename => $tempiface) {
2055
			if ((isset($tempiface['if'])) && (isset($tempiface['ipaddr']) || isset($tempiface['ipaddrv6'])) && !interface_isppp_type($tempifacename)) {
2056
				$tempaddr[$count]['if'] = $tempiface['if'];
2057
				$tempaddr[$count]['ipaddr'] = '192.0.2.' . strval (10 + ($count * 2)) . '/31';
2058
				mwexec('/sbin/ifconfig ' . escapeshellarg($tempaddr[$count]['if']) . ' inet ' . escapeshellarg($tempaddr[$count]['ipaddr']) . ' alias', true);
2059
				$count++;
2060
			}
2061
			// Maximum /31 is is x.y.z.254/31
2062
			if ($count > 122) {
2063
				break;
2064
			}
2065
		}
2066
		unset($count);
2067
	}
2068
2069 3a906378 gnhb
	/* fire up mpd */
2070 631c29af NewEraCracker
	mwexec("/usr/local/sbin/mpd5 -b -k -d {$g['varetc_path']} -f mpd_{$interface}.conf -p " .
2071
		escapeshellarg("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid") . " -s ppp " .
2072
		escapeshellarg("{$ppp['type']}client"));
2073 3a906378 gnhb
2074 be45aa79 Renato Botelho
	// Check for PPPoE periodic reset request
2075 bfbb9bc0 Ermal
	if ($type == "pppoe") {
2076 cf73302f Phil Davis
		if (!empty($ppp['pppoe-reset-type'])) {
2077 70e46e62 Ermal
			interface_setup_pppoe_reset_file($ppp['if'], $interface);
2078 cf73302f Phil Davis
		} else {
2079 70e46e62 Ermal
			interface_setup_pppoe_reset_file($ppp['if']);
2080 cf73302f Phil Davis
		}
2081 cb37d8fa gnhb
	}
2082 302d646e smos
	/* wait for upto 10 seconds for the interface to appear (ppp(oe)) */
2083
	$i = 0;
2084 cf73302f Phil Davis
	while ($i < 3) {
2085 42982b22 Ermal LUÇI
		sleep(10);
2086 cf73302f Phil Davis
		if (does_interface_exist($ppp['if'], true)) {
2087 302d646e smos
			break;
2088 cf73302f Phil Davis
		}
2089 302d646e smos
		$i++;
2090
	}
2091 cb37d8fa gnhb
2092 0c9b98c0 Chris Buechler
	/* Remove all temporary bogon IPv4 addresses */
2093
	if (is_array($tempaddr)) {
2094
		foreach ($tempaddr as $tempiface) {
2095
			if (isset($tempiface['if']) && isset($tempiface['ipaddr'])) {
2096
				mwexec('/sbin/ifconfig ' . escapeshellarg($tempiface['if']) . ' inet ' . escapeshellarg($tempiface['ipaddr']) . ' -alias', true);
2097
			}
2098
		}
2099
		unset ($tempaddr);
2100
	}
2101
2102 117f8e6f smos
	/* we only support the 3gstats.php for huawei modems for now. Will add more later. */
2103
	/* We should be able to launch the right version for each modem */
2104
	/* We can also guess the mondev from the manufacturer */
2105 90987191 doktornotor
	exec("/usr/sbin/usbconfig | /usr/bin/egrep -ie '(huawei)'", $usbmodemoutput);
2106
	mwexec("/bin/ps auxww | /usr/bin/grep \"{$interface}\" | /usr/bin/grep \"[3]gstats\" | /usr/bin/awk '{print $2}' | /usr/bin/xargs kill");
2107 cf73302f Phil Davis
	foreach ($ports as $port) {
2108
		if (preg_match("/huawei/i", implode("\n", $usbmodemoutput))) {
2109 6c07db48 Phil Davis
			$mondev = substr(basename($port), 0, -1);
2110 117f8e6f smos
			$devlist = glob("/dev/{$mondev}?");
2111
			$mondev = basename(end($devlist));
2112 284101d3 smos
		}
2113 cf73302f Phil Davis
		if (preg_match("/zte/i", implode("\n", $usbmodemoutput))) {
2114 6c07db48 Phil Davis
			$mondev = substr(basename($port), 0, -1) . "1";
2115 284101d3 smos
		}
2116 cf73302f Phil Davis
		if ($mondev != '') {
2117 d18f3f6e Phil Davis
			log_error(sprintf(gettext('Starting 3gstats.php on device \'%1$s\' for interface \'%2$s\''), $mondev, $interface));
2118 d69414fe Chris Buechler
			mwexec_bg("/usr/local/bin/3gstats.php {$mondev} {$interface}");
2119
		}
2120 5e589685 smos
	}
2121
2122 23721285 gnhb
	return 1;
2123 cb37d8fa gnhb
}
2124
2125 8ff85c39 Ermal
function interfaces_sync_setup() {
2126 87a2efd1 Ermal Luçi
	global $g, $config;
2127 abcb2bed Ermal Lu?i
2128 84b32407 Ermal
	if (isset($config['system']['developerspew'])) {
2129 b932ef16 Scott Ullrich
		$mt = microtime();
2130 8ff85c39 Ermal
		echo "interfaces_sync_setup() being called $mt\n";
2131 b932ef16 Scott Ullrich
	}
2132 abcb2bed Ermal Lu?i
2133 285ef132 Ermal LUÇI
	if (platform_booting()) {
2134 07e40c1f Carlos Eduardo Ramos
		echo gettext("Configuring CARP settings...");
2135 7d0f4544 Scott Ullrich
		mute_kernel_msgs();
2136 a5250ebc Scott Ullrich
	}
2137 abcb2bed Ermal Lu?i
2138 b932ef16 Scott Ullrich
	/* suck in configuration items */
2139 84b32407 Ermal
	if ($config['hasync']) {
2140 f97a5b04 Darren Embry
		$pfsyncenabled = $config['hasync']['pfsyncenabled'];
2141
		$pfsyncinterface = $config['hasync']['pfsyncinterface'];
2142
		$pfsyncpeerip = $config['hasync']['pfsyncpeerip'];
2143 b932ef16 Scott Ullrich
	} else {
2144
		unset($pfsyncinterface);
2145
		unset($pfsyncenabled);
2146 6008210b Scott Ullrich
	}
2147 abcb2bed Ermal Lu?i
2148 971de1f9 Renato Botelho
	set_sysctl(array(
2149
		"net.inet.carp.preempt" => "1",
2150
		"net.inet.carp.log" => "1")
2151
	);
2152 abcb2bed Ermal Lu?i
2153 cf73302f Phil Davis
	if (!empty($pfsyncinterface)) {
2154 abcb2bed Ermal Lu?i
		$carp_sync_int = get_real_interface($pfsyncinterface);
2155 cf73302f Phil Davis
	} else {
2156 84b32407 Ermal
		unset($carp_sync_int);
2157 cf73302f Phil Davis
	}
2158 abcb2bed Ermal Lu?i
2159 b932ef16 Scott Ullrich
	/* setup pfsync interface */
2160 febe0112 Ermal
	if (isset($carp_sync_int) and isset($pfsyncenabled)) {
2161 cf73302f Phil Davis
		if (is_ipaddr($pfsyncpeerip)) {
2162 dc2e5552 Renato Botelho
			$syncpeer = "syncpeer {$pfsyncpeerip}";
2163 cf73302f Phil Davis
		} else {
2164 dc2e5552 Renato Botelho
			$syncpeer = "-syncpeer";
2165 cf73302f Phil Davis
		}
2166 dc2e5552 Renato Botelho
2167
		mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} {$syncpeer} up", false);
2168 fd07693e Ermal LUÇI
		mwexec("/sbin/ifconfig pfsync0 -defer", false);
2169 abcb2bed Ermal Lu?i
2170 84b32407 Ermal
		sleep(1);
2171 2eb9c02f Ermal
2172 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
2173
		 * for existing sessions.
2174
		 */
2175 d18f3f6e Phil Davis
		log_error(gettext("waiting for pfsync..."));
2176 1be1a67a PiBa-NL
		$i = 0;
2177
		while (intval(trim(`/sbin/ifconfig pfsync0 | /usr/bin/grep 'syncok: 0' | /usr/bin/grep -v grep | /usr/bin/wc -l`)) == 0 && $i < 30) {
2178
			$i++;
2179
			sleep(1);
2180
		}
2181 d18f3f6e Phil Davis
		log_error(sprintf(gettext("pfsync done in %s seconds."), $i));
2182
		log_error(gettext("Configuring CARP settings finalize..."));
2183 b32ea59d Renato Botelho
	} else {
2184 fb6a3e7a Renato Botelho
		mwexec("/sbin/ifconfig pfsync0 -syncdev -syncpeer down", false);
2185 6930e805 Ermal
	}
2186 abcb2bed Ermal Lu?i
2187 985118b8 Luiz Otavio O Souza
	$carplist = get_configured_vip_list('all', VIP_CARP);
2188
	if (isset($carplist) && is_array($carplist) && count($carplist) > 0) {
2189 971de1f9 Renato Botelho
		set_single_sysctl("net.inet.carp.allow", "1");
2190 cf73302f Phil Davis
	} else {
2191 971de1f9 Renato Botelho
		set_single_sysctl("net.inet.carp.allow", "0");
2192 cf73302f Phil Davis
	}
2193 be45aa79 Renato Botelho
2194 285ef132 Ermal LUÇI
	if (platform_booting()) {
2195 abcb2bed Ermal Lu?i
		unmute_kernel_msgs();
2196 07e40c1f Carlos Eduardo Ramos
		echo gettext("done.") . "\n";
2197 abcb2bed Ermal Lu?i
	}
2198 67ee1ec5 Ermal Luçi
}
2199
2200 962fd685 Ermal
function interface_proxyarp_configure($interface = "") {
2201 9006e9f8 Scott Ullrich
	global $config, $g;
2202 cf73302f Phil Davis
	if (isset($config['system']['developerspew'])) {
2203 9006e9f8 Scott Ullrich
		$mt = microtime();
2204
		echo "interface_proxyarp_configure() being called $mt\n";
2205
	}
2206 67ee1ec5 Ermal Luçi
2207 9006e9f8 Scott Ullrich
	/* kill any running choparp */
2208 cf73302f Phil Davis
	if (empty($interface)) {
2209 962fd685 Ermal
		killbyname("choparp");
2210 cf73302f Phil Davis
	} else {
2211 7c73f504 Ermal
		$vipif = get_real_interface($interface);
2212 cf73302f Phil Davis
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid")) {
2213 7c73f504 Ermal
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
2214 cf73302f Phil Davis
		}
2215 7c73f504 Ermal
	}
2216 1b58b513 Scott Ullrich
2217 7c73f504 Ermal
	$paa = array();
2218
	if (!empty($config['virtualip']) && is_array($config['virtualip']['vip'])) {
2219 e5d43d93 Scott Ullrich
2220 9006e9f8 Scott Ullrich
		/* group by interface */
2221
		foreach ($config['virtualip']['vip'] as $vipent) {
2222
			if ($vipent['mode'] === "proxyarp") {
2223 cf73302f Phil Davis
				if ($vipent['interface']) {
2224 9006e9f8 Scott Ullrich
					$proxyif = $vipent['interface'];
2225 cf73302f Phil Davis
				} else {
2226 9006e9f8 Scott Ullrich
					$proxyif = "wan";
2227 cf73302f Phil Davis
				}
2228 be45aa79 Renato Botelho
2229 cf73302f Phil Davis
				if (!empty($interface) && $interface != $proxyif) {
2230 7e96ca27 Ermal
					continue;
2231 cf73302f Phil Davis
				}
2232 abcb2bed Ermal Lu?i
2233 cf73302f Phil Davis
				if (!is_array($paa[$proxyif])) {
2234 9006e9f8 Scott Ullrich
					$paa[$proxyif] = array();
2235 cf73302f Phil Davis
				}
2236 7b2d4769 Bill Marquette
2237 9006e9f8 Scott Ullrich
				$paa[$proxyif][] = $vipent;
2238
			}
2239 962fd685 Ermal
		}
2240 9006e9f8 Scott Ullrich
	}
2241 e5d43d93 Scott Ullrich
2242 962fd685 Ermal
	if (!empty($interface)) {
2243
		if (is_array($paa[$interface])) {
2244
			$paaifip = get_interface_ip($interface);
2245 cf73302f Phil Davis
			if (!is_ipaddr($paaifip)) {
2246 1c3ddd9e Renato Botelho
				return;
2247 cf73302f Phil Davis
			}
2248 1c3ddd9e Renato Botelho
			$args = get_real_interface($interface) . " auto";
2249
			foreach ($paa[$interface] as $paent) {
2250 cf73302f Phil Davis
				if (isset($paent['subnet'])) {
2251 1c3ddd9e Renato Botelho
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
2252 cf73302f Phil Davis
				} else if (isset($paent['range'])) {
2253 1c3ddd9e Renato Botelho
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
2254 cf73302f Phil Davis
				}
2255 1c3ddd9e Renato Botelho
			}
2256
			mwexec_bg("/usr/local/sbin/choparp " . $args);
2257 962fd685 Ermal
		}
2258 7c73f504 Ermal
	} else if (count($paa) > 0) {
2259 6c07db48 Phil Davis
		foreach ($paa as $paif => $paents) {
2260 9006e9f8 Scott Ullrich
			$paaifip = get_interface_ip($paif);
2261 cf73302f Phil Davis
			if (!is_ipaddr($paaifip)) {
2262 9006e9f8 Scott Ullrich
				continue;
2263 cf73302f Phil Davis
			}
2264 9006e9f8 Scott Ullrich
			$args = get_real_interface($paif) . " auto";
2265
			foreach ($paents as $paent) {
2266 cf73302f Phil Davis
				if (isset($paent['subnet'])) {
2267 9006e9f8 Scott Ullrich
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
2268 cf73302f Phil Davis
				} else if (isset($paent['range'])) {
2269 962fd685 Ermal
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
2270 cf73302f Phil Davis
				}
2271 9006e9f8 Scott Ullrich
			}
2272
			mwexec_bg("/usr/local/sbin/choparp " . $args);
2273
		}
2274
	}
2275 9f6b1429 Scott Ullrich
}
2276
2277 94bb4420 Luiz Otavio O Souza
function interface_vip_cleanup($interface, $inet = "all", $type = VIP_ALL) {
2278 4454f1f3 Ermal
	global $g, $config;
2279
2280
	if (is_array($config['virtualip']['vip'])) {
2281
		foreach ($config['virtualip']['vip'] as $vip) {
2282 94bb4420 Luiz Otavio O Souza
2283
			$iface = $vip['interface'];
2284
			if (substr($iface, 0, 4) == "_vip")
2285
				$iface = get_configured_vip_interface($vip['interface']);
2286
			if ($iface != $interface)
2287
				continue;
2288
			if ($type == VIP_CARP) {
2289
				if ($vip['mode'] != "carp")
2290
					continue;
2291
			} elseif ($type == VIP_IPALIAS) {
2292
				if ($vip['mode'] != "ipalias")
2293
					continue;
2294
			} else {
2295
				if ($vip['mode'] != "carp" && $vip['mode'] != "ipalias")
2296
					continue;
2297 4454f1f3 Ermal
			}
2298 94bb4420 Luiz Otavio O Souza
2299
			if ($inet == "inet6" && is_ipaddrv6($vip['subnet']))
2300
				interface_vip_bring_down($vip);
2301
			else if ($inet == "inet4" && is_ipaddrv4($vip['subnet']))
2302
				interface_vip_bring_down($vip);
2303
			else if ($inet == "all")
2304
				interface_vip_bring_down($vip);
2305 4454f1f3 Ermal
		}
2306
	}
2307
}
2308
2309 e5ac67ed Ermal Lu?i
function interfaces_vips_configure($interface = "") {
2310 87a2efd1 Ermal Luçi
	global $g, $config;
2311 cf73302f Phil Davis
	if (isset($config['system']['developerspew'])) {
2312 a04de17f Chris Buechler
		$mt = microtime();
2313 123f030c Chris Buechler
		echo "interfaces_vips_configure() being called $mt\n";
2314 a04de17f Chris Buechler
	}
2315 abcb2bed Ermal Lu?i
	$paa = array();
2316 cf73302f Phil Davis
	if (is_array($config['virtualip']['vip'])) {
2317 abcb2bed Ermal Lu?i
		$carp_setuped = false;
2318 e5ac67ed Ermal Lu?i
		$anyproxyarp = false;
2319 abcb2bed Ermal Lu?i
		foreach ($config['virtualip']['vip'] as $vip) {
2320
			switch ($vip['mode']) {
2321 cf73302f Phil Davis
				case "proxyarp":
2322
					/* nothing it is handled on interface_proxyarp_configure() */
2323
					if ($interface <> "" && $vip['interface'] <> $interface) {
2324
						continue;
2325
					}
2326
					$anyproxyarp = true;
2327
					break;
2328
				case "ipalias":
2329 94bb4420 Luiz Otavio O Souza
					$iface = $vip['interface'];
2330
					if (substr($iface, 0, 4) == "_vip")
2331
						$iface = get_configured_vip_interface($vip['interface']);
2332
					if ($interface <> "" && $iface <> $interface) {
2333 cf73302f Phil Davis
						continue;
2334
					}
2335
					interface_ipalias_configure($vip);
2336
					break;
2337
				case "carp":
2338
					if ($interface <> "" && $vip['interface'] <> $interface) {
2339
						continue;
2340
					}
2341
					if ($carp_setuped == false) {
2342
						$carp_setuped = true;
2343
					}
2344
					interface_carp_configure($vip);
2345
					break;
2346 6a74c90e Scott Ullrich
			}
2347 a04de17f Chris Buechler
		}
2348 cf73302f Phil Davis
		if ($carp_setuped == true) {
2349 8ff85c39 Ermal
			interfaces_sync_setup();
2350 cf73302f Phil Davis
		}
2351
		if ($anyproxyarp == true) {
2352 e5ac67ed Ermal Lu?i
			interface_proxyarp_configure();
2353 cf73302f Phil Davis
		}
2354 abcb2bed Ermal Lu?i
	}
2355
}
2356
2357
function interface_ipalias_configure(&$vip) {
2358 672e28f3 Renato Botelho
	global $config;
2359
2360 cf73302f Phil Davis
	if ($vip['mode'] != 'ipalias') {
2361 672e28f3 Renato Botelho
		return;
2362 cf73302f Phil Davis
	}
2363 672e28f3 Renato Botelho
2364 2a5960b0 Luiz Otavio O Souza
	$realif = get_real_interface("_vip{$vip['uniqid']}");
2365
	if ($realif != "lo0") {
2366
		$if = convert_real_interface_to_friendly_interface_name($realif);
2367
		if (!isset($config['interfaces'][$if])) {
2368 b0d054ca Ermal
			return;
2369 cf73302f Phil Davis
		}
2370 672e28f3 Renato Botelho
2371 2a5960b0 Luiz Otavio O Souza
		if (!isset($config['interfaces'][$if]['enable'])) {
2372 b0d054ca Ermal
			return;
2373 cf73302f Phil Davis
		}
2374 b0d054ca Ermal
	}
2375 672e28f3 Renato Botelho
2376 b0d054ca Ermal
	$af = 'inet';
2377 d9901ff4 Chris Buechler
	if (is_ipaddrv6($vip['subnet'])) {
2378 b0d054ca Ermal
		$af = 'inet6';
2379 d9901ff4 Chris Buechler
	}
2380 b0d054ca Ermal
	$iface = $vip['interface'];
2381 2a5960b0 Luiz Otavio O Souza
	$vhid = '';
2382
	if (substr($vip['interface'], 0, 4) == "_vip") {
2383
		$carpvip = get_configured_vip($vip['interface']);
2384 b0d054ca Ermal
		$iface = $carpvip['interface'];
2385 2a5960b0 Luiz Otavio O Souza
		$vhid = "vhid {$carpvip['vhid']}";
2386 9006e9f8 Scott Ullrich
	}
2387 2a5960b0 Luiz Otavio O Souza
	mwexec("/sbin/ifconfig " . escapeshellarg($realif) ." {$af} ". escapeshellarg($vip['subnet']) ."/" . escapeshellarg($vip['subnet_bits']) . " alias {$vhid}");
2388
	unset($iface, $af, $realif, $carpvip, $vhid);
2389 abcb2bed Ermal Lu?i
}
2390
2391
function interface_carp_configure(&$vip) {
2392
	global $config, $g;
2393 cf73302f Phil Davis
	if (isset($config['system']['developerspew'])) {
2394 58ebf6bb Scott Ullrich
		$mt = microtime();
2395 0a595d84 Ermal Lu?i
		echo "interface_carp_configure() being called $mt\n";
2396 58ebf6bb Scott Ullrich
	}
2397 abcb2bed Ermal Lu?i
2398 cf73302f Phil Davis
	if ($vip['mode'] != "carp") {
2399 abcb2bed Ermal Lu?i
		return;
2400 cf73302f Phil Davis
	}
2401 abcb2bed Ermal Lu?i
2402 f416763b Phil Davis
	/* NOTE: Maybe its useless nowadays */
2403 58ebf6bb Scott Ullrich
	$realif = get_real_interface($vip['interface']);
2404
	if (!does_interface_exist($realif)) {
2405 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", "");
2406 58ebf6bb Scott Ullrich
		return;
2407
	}
2408 abcb2bed Ermal Lu?i
2409 7b47bd4c Ermal
	$vip_password = $vip['password'];
2410
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
2411 cf73302f Phil Davis
	if ($vip['password'] != "") {
2412 7b47bd4c Ermal
		$password = " pass {$vip_password}";
2413 cf73302f Phil Davis
	}
2414 a687f866 Namezero
2415 100b7219 Ermal
	$advbase = "";
2416 cf73302f Phil Davis
	if (!empty($vip['advbase'])) {
2417 873c1701 Renato Botelho
		$advbase = "advbase " . escapeshellarg($vip['advbase']);
2418 cf73302f Phil Davis
	}
2419 1f74cd2d Seth Mos
2420 783f1ee2 PiBa-NL
	$carp_maintenancemode = isset($config["virtualip_carp_maintenancemode"]);
2421 cf73302f Phil Davis
	if ($carp_maintenancemode) {
2422 783f1ee2 PiBa-NL
		$advskew = "advskew 254";
2423 cf73302f Phil Davis
	} else {
2424 783f1ee2 PiBa-NL
		$advskew = "advskew " . escapeshellarg($vip['advskew']);
2425 cf73302f Phil Davis
	}
2426
2427 783f1ee2 PiBa-NL
	mwexec("/sbin/ifconfig {$realif} vhid " . escapeshellarg($vip['vhid']) . " {$advskew} {$advbase} {$password}");
2428 00a6fcb7 Ermal
2429 cf73302f Phil Davis
	if (is_ipaddrv4($vip['subnet'])) {
2430 00a6fcb7 Ermal
		mwexec("/sbin/ifconfig {$realif} " . escapeshellarg($vip['subnet']) . "/" . escapeshellarg($vip['subnet_bits']) . " alias vhid " . escapeshellarg($vip['vhid']));
2431 cf73302f Phil Davis
	} else if (is_ipaddrv6($vip['subnet'])) {
2432 80a261a2 PiBa-NL
		mwexec("/sbin/ifconfig {$realif} inet6 " . escapeshellarg($vip['subnet']) . " prefixlen " . escapeshellarg($vip['subnet_bits']) . " alias vhid " . escapeshellarg($vip['vhid']));
2433 cf73302f Phil Davis
	}
2434 abcb2bed Ermal Lu?i
2435 7238e0cf Ermal
	return $realif;
2436 abcb2bed Ermal Lu?i
}
2437
2438 854aed18 Ermal Lu?i
function interface_wireless_clone($realif, $wlcfg) {
2439 568b1358 Scott Ullrich
	global $config, $g;
2440 be45aa79 Renato Botelho
	/*   Check to see if interface has been cloned as of yet.
2441 88157f66 Scott Ullrich
	 *   If it has not been cloned then go ahead and clone it.
2442
	 */
2443 2a203afd Seth Mos
	$needs_clone = false;
2444 cf73302f Phil Davis
	if (is_array($wlcfg['wireless'])) {
2445 9f428275 Erik Fonnesbeck
		$wlcfg_mode = $wlcfg['wireless']['mode'];
2446 cf73302f Phil Davis
	} else {
2447 9f428275 Erik Fonnesbeck
		$wlcfg_mode = $wlcfg['mode'];
2448 cf73302f Phil Davis
	}
2449 086cf944 Phil Davis
	switch ($wlcfg_mode) {
2450 cf73302f Phil Davis
		case "hostap":
2451
			$mode = "wlanmode hostap";
2452
			break;
2453
		case "adhoc":
2454
			$mode = "wlanmode adhoc";
2455
			break;
2456
		default:
2457
			$mode = "";
2458
			break;
2459 2a203afd Seth Mos
	}
2460 34808d4e Erik Fonnesbeck
	$baseif = interface_get_wireless_base($wlcfg['if']);
2461 cf73302f Phil Davis
	if (does_interface_exist($realif)) {
2462 873c1701 Renato Botelho
		exec("/sbin/ifconfig " . escapeshellarg($realif), $output, $ret);
2463 2a203afd Seth Mos
		$ifconfig_str = implode($output);
2464 086cf944 Phil Davis
		if (($wlcfg_mode == "hostap") && (!preg_match("/hostap/si", $ifconfig_str))) {
2465 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Interface %s changed to hostap mode"), $realif));
2466 2a203afd Seth Mos
			$needs_clone = true;
2467
		}
2468 086cf944 Phil Davis
		if (($wlcfg_mode == "adhoc") && (!preg_match("/adhoc/si", $ifconfig_str))) {
2469 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Interface %s changed to adhoc mode"), $realif));
2470 2a203afd Seth Mos
			$needs_clone = true;
2471
		}
2472 cf73302f Phil Davis
		if (($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
2473 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Interface %s changed to infrastructure mode"), $realif));
2474 2a203afd Seth Mos
			$needs_clone = true;
2475
		}
2476
	} else {
2477
		$needs_clone = true;
2478 88157f66 Scott Ullrich
	}
2479 2a203afd Seth Mos
2480 cf73302f Phil Davis
	if ($needs_clone == true) {
2481 2a203afd Seth Mos
		/* remove previous instance if it exists */
2482 cf73302f Phil Davis
		if (does_interface_exist($realif)) {
2483 871768cf Ermal
			pfSense_interface_destroy($realif);
2484 cf73302f Phil Davis
		}
2485 854aed18 Ermal Lu?i
2486 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("Cloning new wireless interface %s"), $realif));
2487 b99256c1 Scott Ullrich
		// Create the new wlan interface. FreeBSD returns the new interface name.
2488
		// example:  wlan2
2489 6d54e865 Erik Fonnesbeck
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
2490 cf73302f Phil Davis
		if ($ret <> 0) {
2491 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]));
2492 9f428275 Erik Fonnesbeck
			return false;
2493 2a203afd Seth Mos
		}
2494
		$newif = trim($out[0]);
2495
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
2496 871768cf Ermal
		pfSense_interface_rename($newif, $realif);
2497 acb0bce0 Erik Fonnesbeck
		file_put_contents("{$g['tmp_path']}/{$realif}_oldmac", get_interface_mac($realif));
2498 88157f66 Scott Ullrich
	}
2499 9f428275 Erik Fonnesbeck
	return true;
2500 88157f66 Scott Ullrich
}
2501
2502 8f0289e7 Erik Fonnesbeck
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
2503
	global $config, $g;
2504
2505 56626335 Erik Fonnesbeck
	$shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel',
2506 a8f5790a Renato Botelho
				 'diversity', 'txantenna', 'rxantenna', 'distance',
2507
				 'regdomain', 'regcountry', 'reglocation');
2508 8f0289e7 Erik Fonnesbeck
2509 cf73302f Phil Davis
	if (!is_interface_wireless($ifcfg['if'])) {
2510 7de319a1 Erik Fonnesbeck
		return;
2511 cf73302f Phil Davis
	}
2512 7de319a1 Erik Fonnesbeck
2513 34808d4e Erik Fonnesbeck
	$baseif = interface_get_wireless_base($ifcfg['if']);
2514 8f0289e7 Erik Fonnesbeck
2515 062023a5 Erik Fonnesbeck
	// Sync shared settings for assigned clones
2516 38b7d47d Erik Fonnesbeck
	$iflist = get_configured_interface_list(false, true);
2517 8f0289e7 Erik Fonnesbeck
	foreach ($iflist as $if) {
2518 34808d4e Erik Fonnesbeck
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
2519 8f0289e7 Erik Fonnesbeck
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
2520
				foreach ($shared_settings as $setting) {
2521
					if ($sync_changes) {
2522 cf73302f Phil Davis
						if (isset($ifcfg['wireless'][$setting])) {
2523 56626335 Erik Fonnesbeck
							$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
2524 cf73302f Phil Davis
						} else if (isset($config['interfaces'][$if]['wireless'][$setting])) {
2525 56626335 Erik Fonnesbeck
							unset($config['interfaces'][$if]['wireless'][$setting]);
2526 cf73302f Phil Davis
						}
2527 8f0289e7 Erik Fonnesbeck
					} else {
2528 cf73302f Phil Davis
						if (isset($config['interfaces'][$if]['wireless'][$setting])) {
2529 56626335 Erik Fonnesbeck
							$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
2530 cf73302f Phil Davis
						} else if (isset($ifcfg['wireless'][$setting])) {
2531 56626335 Erik Fonnesbeck
							unset($ifcfg['wireless'][$setting]);
2532 cf73302f Phil Davis
						}
2533 8f0289e7 Erik Fonnesbeck
					}
2534
				}
2535 cf73302f Phil Davis
				if (!$sync_changes) {
2536 8f0289e7 Erik Fonnesbeck
					break;
2537 cf73302f Phil Davis
				}
2538 8f0289e7 Erik Fonnesbeck
			}
2539
		}
2540
	}
2541 263e2b7e Erik Fonnesbeck
2542 062023a5 Erik Fonnesbeck
	// Read or write settings at shared area
2543 6ef2297b Erik Fonnesbeck
	if (isset($config['wireless']['interfaces'][$baseif]) && is_array($config['wireless']['interfaces'][$baseif])) {
2544 f62c44d8 Erik Fonnesbeck
		foreach ($shared_settings as $setting) {
2545
			if ($sync_changes) {
2546 cf73302f Phil Davis
				if (isset($ifcfg['wireless'][$setting])) {
2547 56626335 Erik Fonnesbeck
					$config['wireless']['interfaces'][$baseif][$setting] = $ifcfg['wireless'][$setting];
2548 cf73302f Phil Davis
				} else if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
2549 56626335 Erik Fonnesbeck
					unset($config['wireless']['interfaces'][$baseif][$setting]);
2550 cf73302f Phil Davis
				}
2551 f62c44d8 Erik Fonnesbeck
			} else if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
2552 cf73302f Phil Davis
				if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
2553 56626335 Erik Fonnesbeck
					$ifcfg['wireless'][$setting] = $config['wireless']['interfaces'][$baseif][$setting];
2554 cf73302f Phil Davis
				} else if (isset($ifcfg['wireless'][$setting])) {
2555 56626335 Erik Fonnesbeck
					unset($ifcfg['wireless'][$setting]);
2556 cf73302f Phil Davis
				}
2557 f62c44d8 Erik Fonnesbeck
			}
2558 062023a5 Erik Fonnesbeck
		}
2559
	}
2560
2561
	// Sync the mode on the clone creation page with the configured mode on the interface
2562 6ef2297b Erik Fonnesbeck
	if (interface_is_wireless_clone($ifcfg['if']) && isset($config['wireless']['clone']) && is_array($config['wireless']['clone'])) {
2563 263e2b7e Erik Fonnesbeck
		foreach ($config['wireless']['clone'] as &$clone) {
2564
			if ($clone['cloneif'] == $ifcfg['if']) {
2565
				if ($sync_changes) {
2566
					$clone['mode'] = $ifcfg['wireless']['mode'];
2567
				} else {
2568
					$ifcfg['wireless']['mode'] = $clone['mode'];
2569
				}
2570
				break;
2571
			}
2572
		}
2573 867d444b Erik Fonnesbeck
		unset($clone);
2574 263e2b7e Erik Fonnesbeck
	}
2575 8f0289e7 Erik Fonnesbeck
}
2576
2577 19e83210 Scott Ullrich
function interface_wireless_configure($if, &$wl, &$wlcfg) {
2578 ac3f8318 Espen Johansen
	global $config, $g;
2579 eb772abd Scott Ullrich
2580 4742e927 Scott Ullrich
	/*    open up a shell script that will be used to output the commands.
2581
	 *    since wireless is changing a lot, these series of commands are fragile
2582 905ea336 Phil Davis
	 *    and will sometimes need to be verified by a operator by executing the command
2583
	 *    and returning the output of the command to the developers for inspection.  please
2584
	 *    do not change this routine from a shell script to individual exec commands.  -sullrich
2585 4742e927 Scott Ullrich
	 */
2586 eb772abd Scott Ullrich
2587 b99256c1 Scott Ullrich
	// Remove script file
2588 490b8b2a Scott Ullrich
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
2589 eb772abd Scott Ullrich
2590 0a28d385 Erik Fonnesbeck
	// Clone wireless nic if needed.
2591
	interface_wireless_clone($if, $wl);
2592
2593 8f0289e7 Erik Fonnesbeck
	// Reject inadvertent changes to shared settings in case the interface hasn't been configured.
2594
	interface_sync_wireless_clones($wl, false);
2595
2596 086cf944 Phil Davis
	$fd_set = fopen("{$g['tmp_path']}/{$if}_setup.sh", "w");
2597 4742e927 Scott Ullrich
	fwrite($fd_set, "#!/bin/sh\n");
2598 36d0358b Scott Ullrich
	fwrite($fd_set, "# {$g['product_name']} wireless configuration script.\n\n");
2599 086cf944 Phil Davis
2600
	$wlan_setup_log = fopen("{$g['tmp_path']}/{$if}_setup.log", "w");
2601 eb772abd Scott Ullrich
2602 2ac908dd Espen Johansen
	/* set values for /path/program */
2603
	$hostapd = "/usr/sbin/hostapd";
2604
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
2605 4742e927 Scott Ullrich
	$ifconfig = "/sbin/ifconfig";
2606 56626335 Erik Fonnesbeck
	$sysctl = "/sbin/sysctl";
2607 4742e927 Scott Ullrich
	$killall = "/usr/bin/killall";
2608 2ac908dd Espen Johansen
2609 905ea336 Phil Davis
	/* Set all wireless ifconfig variables (split up to get rid of needed checking) */
2610 5508cf57 Scott Ullrich
2611 2a203afd Seth Mos
	$wlcmd = array();
2612 56626335 Erik Fonnesbeck
	$wl_sysctl = array();
2613 2a203afd Seth Mos
	/* Make sure it's up */
2614
	$wlcmd[] = "up";
2615 ac3f8318 Espen Johansen
	/* Set a/b/g standard */
2616 9be20928 Erik Fonnesbeck
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
2617 d325e908 Chris Buechler
	/* skip mode entirely for "auto" */
2618
	if ($wlcfg['standard'] != "auto") {
2619
		$wlcmd[] = "mode " . escapeshellarg($standard);
2620
	}
2621 2a203afd Seth Mos
2622 5030b5eb Erik Fonnesbeck
	/* XXX: Disable ampdu for now on mwl when running in 11n mode
2623
	 * to prevent massive packet loss under certain conditions. */
2624 cf73302f Phil Davis
	if (preg_match("/^mwl/i", $if) && ($standard == "11ng" || $standard == "11na")) {
2625 5030b5eb Erik Fonnesbeck
		$wlcmd[] = "-ampdu";
2626 cf73302f Phil Davis
	}
2627 5030b5eb Erik Fonnesbeck
2628 2a203afd Seth Mos
	/* Set ssid */
2629 cf73302f Phil Davis
	if ($wlcfg['ssid']) {
2630 2a203afd Seth Mos
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
2631 cf73302f Phil Davis
	}
2632 5508cf57 Scott Ullrich
2633 0856c4ac Scott Ullrich
	/* Set 802.11g protection mode */
2634 2a203afd Seth Mos
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
2635 0856c4ac Scott Ullrich
2636 ac3f8318 Espen Johansen
	/* set wireless channel value */
2637 cf73302f Phil Davis
	if (isset($wlcfg['channel'])) {
2638
		if ($wlcfg['channel'] == "0") {
2639 2a203afd Seth Mos
			$wlcmd[] = "channel any";
2640
		} else {
2641
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
2642
		}
2643
	}
2644 2ac908dd Espen Johansen
2645 56626335 Erik Fonnesbeck
	/* Set antenna diversity value */
2646 cf73302f Phil Davis
	if (isset($wlcfg['diversity'])) {
2647 56626335 Erik Fonnesbeck
		$wl_sysctl[] = "diversity=" . escapeshellarg($wlcfg['diversity']);
2648 cf73302f Phil Davis
	}
2649 56626335 Erik Fonnesbeck
2650
	/* Set txantenna value */
2651 cf73302f Phil Davis
	if (isset($wlcfg['txantenna'])) {
2652 56626335 Erik Fonnesbeck
		$wl_sysctl[] = "txantenna=" . escapeshellarg($wlcfg['txantenna']);
2653 cf73302f Phil Davis
	}
2654 56626335 Erik Fonnesbeck
2655
	/* Set rxantenna value */
2656 cf73302f Phil Davis
	if (isset($wlcfg['rxantenna'])) {
2657 56626335 Erik Fonnesbeck
		$wl_sysctl[] = "rxantenna=" . escapeshellarg($wlcfg['rxantenna']);
2658 cf73302f Phil Davis
	}
2659 56626335 Erik Fonnesbeck
2660 f134033e Scott Ullrich
	/* set Distance value */
2661 cf73302f Phil Davis
	if ($wlcfg['distance']) {
2662 f134033e Scott Ullrich
		$distance = escapeshellarg($wlcfg['distance']);
2663 cf73302f Phil Davis
	}
2664 f134033e Scott Ullrich
2665 ac3f8318 Espen Johansen
	/* Set wireless hostap mode */
2666 2a203afd Seth Mos
	if ($wlcfg['mode'] == "hostap") {
2667
		$wlcmd[] = "mediaopt hostap";
2668
	} else {
2669
		$wlcmd[] = "-mediaopt hostap";
2670
	}
2671 ac3f8318 Espen Johansen
2672
	/* Set wireless adhoc mode */
2673 2a203afd Seth Mos
	if ($wlcfg['mode'] == "adhoc") {
2674
		$wlcmd[] = "mediaopt adhoc";
2675
	} else {
2676
		$wlcmd[] = "-mediaopt adhoc";
2677
	}
2678 ac3f8318 Espen Johansen
2679 f416763b Phil Davis
	/* Not necessary to set BSS mode as this is default if adhoc and/or hostap is NOT set */
2680 ac3f8318 Espen Johansen
2681
	/* handle hide ssid option */
2682 cf73302f Phil Davis
	if (isset($wlcfg['hidessid']['enable'])) {
2683 2a203afd Seth Mos
		$wlcmd[] = "hidessid";
2684
	} else {
2685
		$wlcmd[] = "-hidessid";
2686
	}
2687 ac3f8318 Espen Johansen
2688
	/* handle pureg (802.11g) only option */
2689 cf73302f Phil Davis
	if (isset($wlcfg['pureg']['enable'])) {
2690 2a203afd Seth Mos
		$wlcmd[] = "mode 11g pureg";
2691
	} else {
2692
		$wlcmd[] = "-pureg";
2693
	}
2694 ac3f8318 Espen Johansen
2695 ed459692 Erik Fonnesbeck
	/* handle puren (802.11n) only option */
2696 cf73302f Phil Davis
	if (isset($wlcfg['puren']['enable'])) {
2697 ed459692 Erik Fonnesbeck
		$wlcmd[] = "puren";
2698
	} else {
2699
		$wlcmd[] = "-puren";
2700
	}
2701
2702 ac3f8318 Espen Johansen
	/* enable apbridge option */
2703 cf73302f Phil Davis
	if (isset($wlcfg['apbridge']['enable'])) {
2704 2a203afd Seth Mos
		$wlcmd[] = "apbridge";
2705
	} else {
2706
		$wlcmd[] = "-apbridge";
2707
	}
2708 ac3f8318 Espen Johansen
2709
	/* handle turbo option */
2710 cf73302f Phil Davis
	if (isset($wlcfg['turbo']['enable'])) {
2711 2a203afd Seth Mos
		$wlcmd[] = "mediaopt turbo";
2712
	} else {
2713
		$wlcmd[] = "-mediaopt turbo";
2714
	}
2715 ac3f8318 Espen Johansen
2716
	/* handle txpower setting */
2717 f2f34088 Chris Buechler
	// or don't. this has issues at the moment.
2718
	/*
2719 086cf944 Phil Davis
	if ($wlcfg['txpower'] <> "" && is_numeric($wlcfg['txpower'])) {
2720 2a203afd Seth Mos
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
2721 f2f34088 Chris Buechler
	}*/
2722 086cf944 Phil Davis
2723 ac3f8318 Espen Johansen
	/* handle wme option */
2724 cf73302f Phil Davis
	if (isset($wlcfg['wme']['enable'])) {
2725 2a203afd Seth Mos
		$wlcmd[] = "wme";
2726
	} else {
2727
		$wlcmd[] = "-wme";
2728
	}
2729 eb772abd Scott Ullrich
2730 b061a3c6 Matt Smith
	/* Enable wpa if it's configured. No WEP support anymore. */
2731
	if (isset($wlcfg['wpa']['enable'])) {
2732 ac0c4355 Chris Buechler
		$wlcmd[] = "authmode wpa wepmode off ";
2733 2a203afd Seth Mos
	} else {
2734
		$wlcmd[] = "authmode open wepmode off ";
2735 ac3f8318 Espen Johansen
	}
2736
2737 97f3ce0f Phil Davis
	kill_hostapd($if);
2738 c8178bb7 Erik Fonnesbeck
	mwexec(kill_wpasupplicant("{$if}"));
2739
2740 ac3f8318 Espen Johansen
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2741 2a203afd Seth Mos
	conf_mount_rw();
2742 ac3f8318 Espen Johansen
2743
	switch ($wlcfg['mode']) {
2744 cf73302f Phil Davis
		case 'bss':
2745
			if (isset($wlcfg['wpa']['enable'])) {
2746
				$wpa .= <<<EOD
2747 454756b9 Scott Ullrich
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2748 50ad3b7c Scott Ullrich
ctrl_interface_group=0
2749
ap_scan=1
2750 2ac908dd Espen Johansen
#fast_reauth=1
2751 249558a2 Scott Ullrich
network={
2752 454756b9 Scott Ullrich
ssid="{$wlcfg['ssid']}"
2753
scan_ssid=1
2754 2ac908dd Espen Johansen
priority=5
2755
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2756 454756b9 Scott Ullrich
psk="{$wlcfg['wpa']['passphrase']}"
2757 2ac908dd Espen Johansen
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2758
group={$wlcfg['wpa']['wpa_pairwise']}
2759 50ad3b7c Scott Ullrich
}
2760
EOD;
2761
2762 cf73302f Phil Davis
				@file_put_contents("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", $wpa);
2763
				unset($wpa);
2764
			}
2765
			break;
2766
		case 'hostap':
2767
			if (!empty($wlcfg['wpa']['passphrase'])) {
2768
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
2769
			} else {
2770
				$wpa_passphrase = "";
2771
			}
2772
			if (isset($wlcfg['wpa']['enable'])) {
2773
				$wpa .= <<<EOD
2774 459d6351 Scott Ullrich
interface={$if}
2775
driver=bsd
2776
logger_syslog=-1
2777
logger_syslog_level=0
2778
logger_stdout=-1
2779
logger_stdout_level=0
2780 2ac908dd Espen Johansen
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
2781
ctrl_interface={$g['varrun_path']}/hostapd
2782 459d6351 Scott Ullrich
ctrl_interface_group=wheel
2783 2ac908dd Espen Johansen
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
2784
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
2785 b67d192d Scott Ullrich
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
2786 459d6351 Scott Ullrich
ssid={$wlcfg['ssid']}
2787 2ac908dd Espen Johansen
debug={$wlcfg['wpa']['debug_mode']}
2788
wpa={$wlcfg['wpa']['wpa_mode']}
2789
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2790
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
2791 ac3f8318 Espen Johansen
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
2792
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
2793
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
2794 7eadaa9c Scott Ullrich
{$wpa_passphrase}
2795 525d565b Scott Ullrich
2796 459d6351 Scott Ullrich
EOD;
2797 2ac908dd Espen Johansen
2798 cf73302f Phil Davis
				if (isset($wlcfg['wpa']['rsn_preauth'])) {
2799
					$wpa .= <<<EOD
2800 1c92c5b1 Stephen Beaver
# Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP to roam from/to
2801 c9e7d30d Scott Ullrich
rsn_preauth=1
2802
rsn_preauth_interfaces={$if}
2803
2804
EOD;
2805 cf73302f Phil Davis
				}
2806
				if (is_array($wlcfg['wpa']['ieee8021x']) && isset($wlcfg['wpa']['ieee8021x']['enable'])) {
2807
					$wpa .= "ieee8021x=1\n";
2808 c9e7d30d Scott Ullrich
2809 cf73302f Phil Davis
					if (!empty($wlcfg['auth_server_addr']) && !empty($wlcfg['auth_server_shared_secret'])) {
2810
						$auth_server_port = "1812";
2811
						if (!empty($wlcfg['auth_server_port']) && is_numeric($wlcfg['auth_server_port'])) {
2812
							$auth_server_port = intval($wlcfg['auth_server_port']);
2813
						}
2814
						$wpa .= <<<EOD
2815 525d565b Scott Ullrich
2816 5949124c Scott Ullrich
auth_server_addr={$wlcfg['auth_server_addr']}
2817
auth_server_port={$auth_server_port}
2818
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2819 315bdf65 Ermal
2820
EOD;
2821 cf73302f Phil Davis
						if (!empty($wlcfg['auth_server_addr2']) && !empty($wlcfg['auth_server_shared_secret2'])) {
2822
							$auth_server_port2 = "1812";
2823
							if (!empty($wlcfg['auth_server_port2']) && is_numeric($wlcfg['auth_server_port2'])) {
2824
								$auth_server_port2 = intval($wlcfg['auth_server_port2']);
2825
							}
2826 315bdf65 Ermal
2827 cf73302f Phil Davis
							$wpa .= <<<EOD
2828 a687f866 Namezero
auth_server_addr={$wlcfg['auth_server_addr2']}
2829
auth_server_port={$auth_server_port2}
2830
auth_server_shared_secret={$wlcfg['auth_server_shared_secret2']}
2831 525d565b Scott Ullrich
2832 459d6351 Scott Ullrich
EOD;
2833 cf73302f Phil Davis
						}
2834 315bdf65 Ermal
					}
2835 5949124c Scott Ullrich
				}
2836 315bdf65 Ermal
2837 cf73302f Phil Davis
				@file_put_contents("{$g['varetc_path']}/hostapd_{$if}.conf", $wpa);
2838
				unset($wpa);
2839
			}
2840
			break;
2841 eb772abd Scott Ullrich
	}
2842 ac3f8318 Espen Johansen
2843 4742e927 Scott Ullrich
	/*
2844
	 *    all variables are set, lets start up everything
2845 2a203afd Seth Mos
	 */
2846 eb772abd Scott Ullrich
2847 bbfc810e Erik Fonnesbeck
	$baseif = interface_get_wireless_base($if);
2848 56626335 Erik Fonnesbeck
	preg_match("/^(.*?)([0-9]*)$/", $baseif, $baseif_split);
2849
	$wl_sysctl_prefix = 'dev.' . $baseif_split[1] . '.' . $baseif_split[2];
2850
2851
	/* set sysctls for the wireless interface */
2852
	if (!empty($wl_sysctl)) {
2853
		fwrite($fd_set, "# sysctls for {$baseif}\n");
2854
		foreach ($wl_sysctl as $wl_sysctl_line) {
2855
			fwrite($fd_set, "{$sysctl} {$wl_sysctl_prefix}.{$wl_sysctl_line}\n");
2856
		}
2857
	}
2858 bbfc810e Erik Fonnesbeck
2859 78922914 Scott Ullrich
	/* set ack timers according to users preference (if he/she has any) */
2860 cf73302f Phil Davis
	if ($distance) {
2861 4742e927 Scott Ullrich
		fwrite($fd_set, "# Enable ATH distance settings\n");
2862 e327021d Erik Fonnesbeck
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2863 78922914 Scott Ullrich
	}
2864 eb772abd Scott Ullrich
2865 ac3f8318 Espen Johansen
	if (isset($wlcfg['wpa']['enable'])) {
2866 2a203afd Seth Mos
		if ($wlcfg['mode'] == "bss") {
2867 4742e927 Scott Ullrich
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2868 2a203afd Seth Mos
		}
2869
		if ($wlcfg['mode'] == "hostap") {
2870 864bf774 Erik Fonnesbeck
			/* add line to script to restore old mac to make hostapd happy */
2871 acb0bce0 Erik Fonnesbeck
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2872
				$if_oldmac = file_get_contents("{$g['tmp_path']}/{$if}_oldmac");
2873 cf73302f Phil Davis
				if (is_macaddr($if_oldmac)) {
2874 acb0bce0 Erik Fonnesbeck
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2875
						" link " . escapeshellarg($if_oldmac) . "\n");
2876 cf73302f Phil Davis
				}
2877 acb0bce0 Erik Fonnesbeck
			}
2878
2879 97f3ce0f Phil Davis
			fwrite($fd_set, "{$hostapd} -B -P {$g['varrun_path']}/hostapd_{$if}.pid {$g['varetc_path']}/hostapd_{$if}.conf\n");
2880 864bf774 Erik Fonnesbeck
2881
			/* add line to script to restore spoofed mac after running hostapd */
2882
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2883 cf73302f Phil Davis
				if ($wl['spoofmac']) {
2884 864bf774 Erik Fonnesbeck
					$if_curmac = $wl['spoofmac'];
2885 cf73302f Phil Davis
				} else {
2886 864bf774 Erik Fonnesbeck
					$if_curmac = get_interface_mac($if);
2887 cf73302f Phil Davis
				}
2888
				if (is_macaddr($if_curmac)) {
2889 864bf774 Erik Fonnesbeck
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2890
						" link " . escapeshellarg($if_curmac) . "\n");
2891 cf73302f Phil Davis
				}
2892 864bf774 Erik Fonnesbeck
			}
2893 2a203afd Seth Mos
		}
2894 ac3f8318 Espen Johansen
	}
2895 191a8175 Scott Ullrich
2896 4742e927 Scott Ullrich
	fclose($fd_set);
2897 8a958125 Scott Ullrich
	conf_mount_ro();
2898
2899 bbfc810e Erik Fonnesbeck
	/* Making sure regulatory settings have actually changed
2900
	 * before applying, because changing them requires bringing
2901
	 * down all wireless networks on the interface. */
2902
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2903
	$ifconfig_str = implode($output);
2904
	unset($output);
2905
	$reg_changing = false;
2906
2907 89e7778f Erik Fonnesbeck
	/* special case for the debug country code */
2908 cf73302f Phil Davis
	if ($wlcfg['regcountry'] == 'DEBUG' && !preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str)) {
2909 89e7778f Erik Fonnesbeck
		$reg_changing = true;
2910 cf73302f Phil Davis
	} else if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str)) {
2911 bbfc810e Erik Fonnesbeck
		$reg_changing = true;
2912 cf73302f Phil Davis
	} else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str)) {
2913 bbfc810e Erik Fonnesbeck
		$reg_changing = true;
2914 cf73302f Phil Davis
	} else if ($wlcfg['reglocation'] == 'anywhere' && preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str)) {
2915 89e7778f Erik Fonnesbeck
		$reg_changing = true;
2916 cf73302f Phil Davis
	} else if ($wlcfg['reglocation'] && $wlcfg['reglocation'] != 'anywhere' && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str)) {
2917 bbfc810e Erik Fonnesbeck
		$reg_changing = true;
2918 cf73302f Phil Davis
	}
2919 bbfc810e Erik Fonnesbeck
2920
	if ($reg_changing) {
2921
		/* set regulatory domain */
2922 cf73302f Phil Davis
		if ($wlcfg['regdomain']) {
2923 bbfc810e Erik Fonnesbeck
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2924 cf73302f Phil Davis
		}
2925 bbfc810e Erik Fonnesbeck
2926
		/* set country */
2927 cf73302f Phil Davis
		if ($wlcfg['regcountry']) {
2928 bbfc810e Erik Fonnesbeck
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2929 cf73302f Phil Davis
		}
2930 bbfc810e Erik Fonnesbeck
2931
		/* set location */
2932 cf73302f Phil Davis
		if ($wlcfg['reglocation']) {
2933 bbfc810e Erik Fonnesbeck
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2934 cf73302f Phil Davis
		}
2935 bbfc810e Erik Fonnesbeck
2936
		$wlregcmd_args = implode(" ", $wlregcmd);
2937
2938
		/* build a complete list of the wireless clones for this interface */
2939
		$clone_list = array();
2940 cf73302f Phil Davis
		if (does_interface_exist(interface_get_wireless_clone($baseif))) {
2941 bbfc810e Erik Fonnesbeck
			$clone_list[] = interface_get_wireless_clone($baseif);
2942 cf73302f Phil Davis
		}
2943 6ef2297b Erik Fonnesbeck
		if (isset($config['wireless']['clone']) && is_array($config['wireless']['clone'])) {
2944 bbfc810e Erik Fonnesbeck
			foreach ($config['wireless']['clone'] as $clone) {
2945 cf73302f Phil Davis
				if ($clone['if'] == $baseif) {
2946 bbfc810e Erik Fonnesbeck
					$clone_list[] = $clone['cloneif'];
2947 cf73302f Phil Davis
				}
2948 bbfc810e Erik Fonnesbeck
			}
2949
		}
2950
2951
		/* find which clones are up and bring them down */
2952
		$clones_up = array();
2953
		foreach ($clone_list as $clone_if) {
2954 1cf76394 Erik Fonnesbeck
			$clone_status = pfSense_get_interface_addresses($clone_if);
2955 bbfc810e Erik Fonnesbeck
			if ($clone_status['status'] == 'up') {
2956
				$clones_up[] = $clone_if;
2957
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2958
			}
2959
		}
2960
2961
		/* apply the regulatory settings */
2962
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2963 95d2d24b Chris Buechler
		fwrite($wlan_setup_log, "$ifconfig" . escapeshellarg($if) . "$wlregcmd_args \n");
2964 bbfc810e Erik Fonnesbeck
2965
		/* bring the clones back up that were previously up */
2966
		foreach ($clones_up as $clone_if) {
2967 5e0a3256 Ermal LUÇI
			interfaces_bring_up($clone_if);
2968 67e77adf Erik Fonnesbeck
2969
			/*
2970
			 * Rerun the setup script for the interface if it isn't this interface, the interface
2971
			 * is in infrastructure mode, and WPA is enabled.
2972
			 * This can be removed if wpa_supplicant stops dying when you bring the interface down.
2973
			 */
2974
			if ($clone_if != $if) {
2975
				$friendly_if = convert_real_interface_to_friendly_interface_name($clone_if);
2976 cf73302f Phil Davis
				if ((!empty($friendly_if)) &&
2977
				    ($config['interfaces'][$friendly_if]['wireless']['mode'] == "bss") &&
2978
				    (isset($config['interfaces'][$friendly_if]['wireless']['wpa']['enable']))) {
2979 873c1701 Renato Botelho
					mwexec("/bin/sh {$g['tmp_path']}/" . escapeshellarg($clone_if) . "_setup.sh");
2980 67e77adf Erik Fonnesbeck
				}
2981
			}
2982 bbfc810e Erik Fonnesbeck
		}
2983
	}
2984
2985 086cf944 Phil Davis
	/* 20150318 cmb - Note: the below no longer appears to be true on FreeBSD 10.x, so don't set
2986 d325e908 Chris Buechler
	 * mode twice (for now at least). This can be removed entirely in the future if no problems are found
2987 086cf944 Phil Davis
2988 d325e908 Chris Buechler
	 * The mode must be specified in a separate command before ifconfig
2989 23fdc06e Erik Fonnesbeck
	 * will allow the mode and channel at the same time in the next. */
2990 d325e908 Chris Buechler
	//mwexec("/sbin/ifconfig " . escapeshellarg($if) . " mode " . escapeshellarg($standard));
2991
	//fwrite($wlan_setup_log, "/sbin/ifconfig " . escapeshellarg($if) . " mode " . escapeshellarg($standard) . "\n");
2992 23fdc06e Erik Fonnesbeck
2993 2a48a885 Erik Fonnesbeck
	/* configure wireless */
2994
	$wlcmd_args = implode(" ", $wlcmd);
2995 873c1701 Renato Botelho
	mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $wlcmd_args, false);
2996 95d2d24b Chris Buechler
	fwrite($wlan_setup_log, "/sbin/ifconfig " . escapeshellarg($if) . " " . "$wlcmd_args \n");
2997
	fclose($wlan_setup_log);
2998 086cf944 Phil Davis
2999 315bdf65 Ermal
	unset($wlcmd_args, $wlcmd);
3000 2a48a885 Erik Fonnesbeck
3001 be45aa79 Renato Botelho
3002 2a203afd Seth Mos
	sleep(1);
3003
	/* execute hostapd and wpa_supplicant if required in shell */
3004 873c1701 Renato Botelho
	mwexec("/bin/sh {$g['tmp_path']}/" . escapeshellarg($if) . "_setup.sh");
3005 191a8175 Scott Ullrich
3006 ac3f8318 Espen Johansen
	return 0;
3007 cfc707f7 Scott Ullrich
3008 5b237745 Scott Ullrich
}
3009
3010 eba938e3 Scott Ullrich
function kill_hostapd($interface) {
3011 97f3ce0f Phil Davis
	global $g;
3012
3013 cf73302f Phil Davis
	if (isvalidpid("{$g['varrun_path']}/hostapd_{$interface}.pid")) {
3014 97f3ce0f Phil Davis
		return killbypid("{$g['varrun_path']}/hostapd_{$interface}.pid");
3015 cf73302f Phil Davis
	}
3016 4b2a6180 Scott Ullrich
}
3017
3018 eba938e3 Scott Ullrich
function kill_wpasupplicant($interface) {
3019 31b958d5 Erik Fonnesbeck
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\\.conf\"\n";
3020 4b2a6180 Scott Ullrich
}
3021
3022 eba938e3 Scott Ullrich
function find_dhclient_process($interface) {
3023 cf73302f Phil Davis
	if ($interface) {
3024 05c4bfa0 Ermal
		$pid = `/bin/pgrep -axf "dhclient: {$interface}"`;
3025 cf73302f Phil Davis
	} else {
3026 319cbd5e Ermal
		$pid = 0;
3027 cf73302f Phil Davis
	}
3028 319cbd5e Ermal
3029 bcfe4ae5 Ermal
	return intval($pid);
3030 0311dbd5 Scott Ullrich
}
3031
3032 d9d1bd20 Renato Botelho
function kill_dhclient_process($interface) {
3033 cf73302f Phil Davis
	if (empty($interface) || !does_interface_exist($interface)) {
3034 d9d1bd20 Renato Botelho
		return;
3035 cf73302f Phil Davis
	}
3036 d9d1bd20 Renato Botelho
3037
	$i = 0;
3038
	while ((($pid = find_dhclient_process($interface)) != 0) && ($i < 3)) {
3039
		/* 3rd time make it die for sure */
3040
		$sig = ($i == 2 ? SIGKILL : SIGTERM);
3041
		posix_kill($pid, $sig);
3042
		sleep(1);
3043
		$i++;
3044
	}
3045
	unset($i);
3046
}
3047
3048 c495f88b Seth Mos
function find_dhcp6c_process($interface) {
3049 b0059636 Ermal
	global $g;
3050
3051 cf73302f Phil Davis
	if ($interface && isvalidpid("{$g['varrun_path']}/dhcp6c_{$interface}.pid")) {
3052 4e6667b2 Renato Botelho
		$pid = trim(file_get_contents("{$g['varrun_path']}/dhcp6c_{$interface}.pid"), " \n");
3053 cf73302f Phil Davis
	} else {
3054 74fa57aa smos
		return(false);
3055 cf73302f Phil Davis
	}
3056 c495f88b Seth Mos
3057
	return intval($pid);
3058
}
3059
3060 f50f74a4 Phil Davis
function kill_dhcp6client_process($interface) {
3061 e0bc2a6c marjohn56
	if (empty($interface) || !does_interface_exist($interface)) {
3062
		return;
3063
	}
3064
3065
	if (($pid = find_dhcp6c_process($interface)) != 0) {
3066
		mwexec("kill -9 {$pid}");
3067
		sleep(1);
3068
	}
3069 f50f74a4 Phil Davis
}
3070
3071 00e8315b Ermal
function interface_virtual_create($interface) {
3072
	global $config;
3073
3074
	if (strstr($interface, "_vlan")) {
3075
		interfaces_vlan_configure($vlan);
3076
	} else if (substr($interface, 0, 3) == "gre") {
3077
		interfaces_gre_configure(0, $interface);
3078
	} else if (substr($interface, 0, 3) == "gif") {
3079
		interfaces_gif_configure(0, $interface);
3080
	} else if (substr($interface, 0, 5) == "ovpns") {
3081
		if (is_array($config['openvpn']) && is_array($config['openvpn']['openvpn-server'])) {
3082
			foreach ($config['openvpn']['openvpn-server'] as $server) {
3083
				if ($interface == "ovpns{$server['vpnid']}") {
3084 cf73302f Phil Davis
					if (!function_exists('openvpn_resync')) {
3085 00e8315b Ermal
						require_once('openvpn.inc');
3086 cf73302f Phil Davis
					}
3087 d18f3f6e Phil Davis
					log_error(sprintf(gettext("OpenVPN: Resync server %s"), $server['description']));
3088 00e8315b Ermal
					openvpn_resync('server', $server);
3089
				}
3090
			}
3091
			unset($server);
3092
		}
3093
	} else if (substr($interface, 0, 5) == "ovpnc") {
3094
		if (is_array($config['openvpn']) && is_array($config['openvpn']['openvpn-client'])) {
3095
			foreach ($config['openvpn']['openvpn-client'] as $client) {
3096
				if ($interface == "ovpnc{$client['vpnid']}") {
3097 cf73302f Phil Davis
					if (!function_exists('openvpn_resync')) {
3098 00e8315b Ermal
						require_once('openvpn.inc');
3099 cf73302f Phil Davis
					}
3100 d18f3f6e Phil Davis
					log_error(sprintf(gettext("OpenVPN: Resync client %s"), $client['description']));
3101 00e8315b Ermal
					openvpn_resync('client', $client);
3102
				}
3103
			}
3104
			unset($client);
3105
		}
3106
	} else if (substr($interface, 0, 4) == "lagg") {
3107
		interfaces_lagg_configure($interface);
3108
	} else if (substr($interface, 0, 6) == "bridge") {
3109
		interfaces_bridge_configure(0, $interface);
3110
	}
3111
}
3112
3113 89c8934f Luiz Otavio O Souza
function interface_vlan_mtu_configured($iface) {
3114 7d5fc0b3 Ermal LUÇI
	global $config;
3115
3116 89c8934f Luiz Otavio O Souza
	$mtu = 0;
3117 7d5fc0b3 Ermal LUÇI
	if (is_array($config['vlans']) && is_array($config['vlans']['vlan'])) {
3118
		foreach ($config['vlans']['vlan'] as $vlan) {
3119 89c8934f Luiz Otavio O Souza
3120
			if ($vlan['vlanif'] != $iface)
3121 7d5fc0b3 Ermal LUÇI
				continue;
3122 89c8934f Luiz Otavio O Souza
3123 7d5fc0b3 Ermal LUÇI
			$assignedport = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
3124
			if (!empty($assignedport) && !empty($config['interfaces'][$assignedport]['mtu'])) {
3125 89c8934f Luiz Otavio O Souza
				/* VLAN MTU */
3126
				$mtu = $config['interfaces'][$assignedport]['mtu'];
3127
			} elseif (!empty($config['interfaces'][$vlan['if']]['mtu'])) {
3128
				/* Parent MTU */
3129
				$mtu = $config['interfaces'][$vlan['if']]['mtu'];
3130 4cd0e27d David Wood
			}
3131 7d5fc0b3 Ermal LUÇI
		}
3132
	}
3133
3134
	return $mtu;
3135
}
3136
3137 65176697 David Wood
function interface_mtu_wanted_for_pppoe($realif) {
3138
	global $config;
3139
3140 89c8934f Luiz Otavio O Souza
	if (!is_array($config['ppps']) || !is_array($config['ppps']['ppp']))
3141
		return 0;
3142 12ca72ba Renato Botelho
3143 89c8934f Luiz Otavio O Souza
	$mtu = 0;
3144 12ca72ba Renato Botelho
	foreach ($config['ppps']['ppp'] as $ppp) {
3145
		if ($ppp['type'] != "pppoe") {
3146
			continue;
3147
		}
3148
3149 e3ad8ccd NewEraCracker
		$mtus = array();
3150
		if (!empty($ppp['mtu'])) {
3151
			$mtus = explode(',', $ppp['mtu']);
3152
		}
3153 f52508b7 Renato Botelho
		$ports = explode(',', $ppp['ports']);
3154 e3ad8ccd NewEraCracker
3155 12ca72ba Renato Botelho
		foreach ($ports as $pid => $port) {
3156 89c8934f Luiz Otavio O Souza
			$parentifa = get_parent_interface($port);
3157
			$parentif = $parentifa[0];
3158
			if ($parentif != $realif)
3159 12ca72ba Renato Botelho
				continue;
3160
3161
			// there is an MTU configured on the port in question
3162
			if (!empty($mtus[$pid])) {
3163 89c8934f Luiz Otavio O Souza
				$mtu = intval($mtus[$pid]) + 8;
3164 12ca72ba Renato Botelho
			// or use the MTU configured on the interface ...
3165
			} elseif (is_array($config['interfaces'])) {
3166
				foreach ($config['interfaces'] as $interface) {
3167
					if ($interface['if'] == $ppp['if'] &&
3168
					    !empty($interface['mtu'])) {
3169 89c8934f Luiz Otavio O Souza
						$mtu = intval($interface['mtu']) + 8;
3170 12ca72ba Renato Botelho
						break;
3171 65176697 David Wood
					}
3172
				}
3173
			}
3174
		}
3175
	}
3176
3177
	return $mtu;
3178
}
3179
3180 7413cbfd Ermal
function interface_configure($interface = "wan", $reloadall = false, $linkupevent = false) {
3181 675aac3d Ermal Luçi
	global $config, $g;
3182 31b24870 Ermal Luçi
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
3183 3502b5b1 Seth Mos
	global $interface_snv6_arr_cache, $interface_ipv6_arr_cache;
3184 cfc707f7 Scott Ullrich
3185 67ee1ec5 Ermal Luçi
	$wancfg = $config['interfaces'][$interface];
3186
3187 cf73302f Phil Davis
	if (!isset($wancfg['enable'])) {
3188 e017a46a Ermal
		return;
3189 cf73302f Phil Davis
	}
3190 e017a46a Ermal
3191 85a5da13 Ermal Luçi
	$realif = get_real_interface($interface);
3192 20cb9803 gnhb
	$realhwif_array = get_parent_interface($interface);
3193
	// Need code to handle MLPPP if we ever use $realhwif for MLPPP handling
3194
	$realhwif = $realhwif_array[0];
3195 cfc707f7 Scott Ullrich
3196 285ef132 Ermal LUÇI
	if (!platform_booting() && !(substr($realif, 0, 4) == "ovpn")) {
3197 3c5e10fc Seth Mos
		/* remove all IPv4 and IPv6 addresses */
3198 c289c48a Ermal
		$tmpifaces = pfSense_getall_interface_addresses($realif);
3199
		if (is_array($tmpifaces)) {
3200
			foreach ($tmpifaces as $tmpiface) {
3201 6b13f8d2 Renato Botelho
				if (is_ipaddrv6($tmpiface) || is_subnetv6($tmpiface)) {
3202 cf73302f Phil Davis
					if (!is_linklocal($tmpiface)) {
3203 6b13f8d2 Renato Botelho
						mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$tmpiface} delete");
3204 cf73302f Phil Davis
					}
3205 6b13f8d2 Renato Botelho
				} else {
3206 d130cd46 Renato Botelho
					if (is_subnetv4($tmpiface)) {
3207
						$tmpip = explode('/', $tmpiface);
3208
						$tmpip = $tmpip[0];
3209 cf73302f Phil Davis
					} else {
3210 d130cd46 Renato Botelho
						$tmpip = $tmpiface;
3211 cf73302f Phil Davis
					}
3212 d130cd46 Renato Botelho
					pfSense_interface_deladdress($realif, $tmpip);
3213
				}
3214 c289c48a Ermal
			}
3215
		}
3216 3896d93e Erik Fonnesbeck
3217 8103bd1e Seth Mos
		/* only bring down the interface when both v4 and v6 are set to NONE */
3218 cf73302f Phil Davis
		if (empty($wancfg['ipaddr']) && empty($wancfg['ipaddrv6'])) {
3219 8103bd1e Seth Mos
			interface_bring_down($interface);
3220 cf73302f Phil Davis
		}
3221 28d22199 Scott Ullrich
	}
3222 acc1e9d0 Scott Ullrich
3223 00e8315b Ermal
	$interface_to_check = $realif;
3224 cf73302f Phil Davis
	if (interface_isppp_type($interface)) {
3225 00e8315b Ermal
		$interface_to_check = $realhwif;
3226 cf73302f Phil Davis
	}
3227 00e8315b Ermal
3228
	/* Need to check that the interface exists or not in the case where its coming back from disabled state see #3270 */
3229 cf73302f Phil Davis
	if (!platform_booting() && (in_array(substr($realif, 0, 3), array("gre", "gif")) || !does_interface_exist($interface_to_check))) {
3230 00e8315b Ermal
		interface_virtual_create($interface_to_check);
3231 cf73302f Phil Davis
	}
3232 00e8315b Ermal
3233
	/* Disable Accepting router advertisements unless specifically requested */
3234 cf73302f Phil Davis
	if ($g['debug']) {
3235 d18f3f6e Phil Davis
		log_error(sprintf(gettext("Deny router advertisements for interface %s"), $interface));
3236 cf73302f Phil Davis
	}
3237 5b7c2403 Ermal LUÇI
	mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -accept_rtadv", true);
3238 00e8315b Ermal
3239 0a28d385 Erik Fonnesbeck
	/* wireless configuration? */
3240 cf73302f Phil Davis
	if (is_array($wancfg['wireless'])) {
3241 0a28d385 Erik Fonnesbeck
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
3242 cf73302f Phil Davis
	}
3243 cfc707f7 Scott Ullrich
3244 49db607f jim-p
	$mac = get_interface_mac($realhwif);
3245 1489e8c8 Renato Botelho
	/*
3246
	 * Don't try to reapply the spoofed MAC if it's already applied.
3247
	 * When ifconfig link is used, it cycles the interface down/up, which triggers
3248
	 * the interface config again, which attempts to spoof the MAC again,
3249
	 * which cycles the link again...
3250
	 */
3251 49db607f jim-p
	if ($wancfg['spoofmac'] && ($wancfg['spoofmac'] != $mac)) {
3252 3e5d0d1d Ermal
		mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
3253 5b237745 Scott Ullrich
			" link " . escapeshellarg($wancfg['spoofmac']));
3254 6c07db48 Phil Davis
	} else {
3255 a687f866 Namezero
3256 3e5d0d1d Ermal
		if ($mac == "ff:ff:ff:ff:ff:ff") {
3257 f36d4bd2 Scott Ullrich
			/*   this is not a valid mac address.  generate a
3258
			 *   temporary mac address so the machine can get online.
3259
			 */
3260 07e40c1f Carlos Eduardo Ramos
			echo gettext("Generating new MAC address.");
3261 f36d4bd2 Scott Ullrich
			$random_mac = generate_random_mac_address();
3262 3e5d0d1d Ermal
			mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
3263 f36d4bd2 Scott Ullrich
				" link " . escapeshellarg($random_mac));
3264
			$wancfg['spoofmac'] = $random_mac;
3265
			write_config();
3266 addc0439 Renato Botelho
			file_notice("MAC Address altered", sprintf(gettext('The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface %1$s has been automatically replaced with %2$s'), $realif, $random_mac), "Interfaces");
3267 f36d4bd2 Scott Ullrich
		}
3268
	}
3269 cfc707f7 Scott Ullrich
3270 5b237745 Scott Ullrich
	/* media */
3271
	if ($wancfg['media'] || $wancfg['mediaopt']) {
3272 3e5d0d1d Ermal
		$cmd = "/sbin/ifconfig " . escapeshellarg($realhwif);
3273 cf73302f Phil Davis
		if ($wancfg['media']) {
3274 5b237745 Scott Ullrich
			$cmd .= " media " . escapeshellarg($wancfg['media']);
3275 cf73302f Phil Davis
		}
3276
		if ($wancfg['mediaopt']) {
3277 5b237745 Scott Ullrich
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
3278 cf73302f Phil Davis
		}
3279 5b237745 Scott Ullrich
		mwexec($cmd);
3280
	}
3281 51d5aad7 Ermal
3282 43517fcc Ermal LUÇI
	/* Apply hw offloading policies as configured */
3283
	enable_hardware_offloading($interface);
3284 51d5aad7 Ermal
3285 a46dc3c7 Chris Buechler
	/* invalidate interface/ip/sn cache */
3286 eba938e3 Scott Ullrich
	get_interface_arr(true);
3287 31b24870 Ermal Luçi
	unset($interface_ip_arr_cache[$realif]);
3288
	unset($interface_sn_arr_cache[$realif]);
3289 5a5413bb Seth Mos
	unset($interface_ipv6_arr_cache[$realif]);
3290
	unset($interface_snv6_arr_cache[$realif]);
3291 ccbd2447 Ermal Luçi
3292 6191b321 Ermal
	$tunnelif = substr($realif, 0, 3);
3293 ffeb5acf Scott Ullrich
3294 4cd0e27d David Wood
	$mtuif = $realif;
3295
	$mtuhwif = $realhwif;
3296
3297
	/* adjust MTU of parent interface of PPPoE interface if this does not violate explicit configuration */
3298
	if (interface_isppp_type($interface)) {
3299
		$mtuif = $realhwif;
3300
		$mtuhwif_array = get_parent_interface($mtuif);
3301
		$mtuhwif = $mtuhwif_array[0];
3302
	}
3303
3304 89c8934f Luiz Otavio O Souza
	$wantedmtu = 0;
3305 4cd0e27d David Wood
	if (is_array($config['interfaces'])) {
3306
		foreach ($config['interfaces'] as $tmpinterface) {
3307
			if ($tmpinterface['if'] == $mtuif && !empty($tmpinterface['mtu'])) {
3308
				$wantedmtu = $tmpinterface['mtu'];
3309
				break;
3310
			}
3311
		}
3312
	}
3313
3314 89c8934f Luiz Otavio O Souza
	/* MTU is not specified for interface, try the pppoe settings. */
3315
	if ($wantedmtu == 0) {
3316
		$wantedmtu = interface_mtu_wanted_for_pppoe($mtuif);
3317
	}
3318
	if ($wantedmtu == 0 && stristr($mtuif, "_vlan") && interface_isppp_type($interface)) {
3319
		$wantedmtu = interface_mtu_wanted_for_pppoe($mtuhwif);
3320
	}
3321
3322
	/* Set the MTU to 1500 if no explicit MTU configured. */
3323 60e15be2 David Wood
	if ($wantedmtu == 0) {
3324
		$wantedmtu = 1500; /* Default */
3325 80f142db David Wood
	}
3326
3327 60e15be2 David Wood
	if (stristr($mtuif, "_vlan")) {
3328
		$assignedparent = convert_real_interface_to_friendly_interface_name($mtuhwif);
3329 c399d0dd Renato Botelho
		if (!empty($assignedparent) && !empty($config['interfaces'][$assignedparent]['mtu'])) {
3330
			$parentmtu = $config['interfaces'][$assignedparent]['mtu'];
3331 60e15be2 David Wood
			if ($wancfg['mtu'] > $parentmtu) {
3332 d18f3f6e Phil Davis
				log_error(sprintf(gettext('There is a conflict on MTU between parent %1$s and VLAN(%2$s)'), $mtuhwif, $mtuif));
3333 cf73302f Phil Davis
			}
3334 c399d0dd Renato Botelho
		}
3335 be2c39b6 Renato Botelho
3336 89c8934f Luiz Otavio O Souza
		$configuredmtu = interface_vlan_mtu_configured($mtuif);
3337 3e8035da Ermal LUÇI
3338 89c8934f Luiz Otavio O Souza
		if ($configuredmtu != 0 && $configuredmtu > $parentmtu)
3339
			$configuredmtu = $parentmtu;
3340
		if ($configuredmtu != 0)
3341
			$mtu = $configuredmtu;
3342
		else
3343
			$mtu = $wantedmtu;
3344 be2c39b6 Renato Botelho
3345 89c8934f Luiz Otavio O Souza
		/* Set the parent MTU. */
3346
		if (get_interface_mtu($mtuhwif) < $mtu)
3347
			set_interface_mtu($mtuhwif, $mtu);
3348
		/* Set the VLAN MTU. */
3349
		if (get_interface_mtu($mtuif) != $mtu)
3350
			set_interface_mtu($mtuif, $mtu);
3351 60e15be2 David Wood
	} else if (substr($mtuif, 0, 4) == 'lagg') {
3352 c399d0dd Renato Botelho
		/* LAGG interface must be destroyed and re-created to change MTU */
3353 60e15be2 David Wood
		if ($wantedmtu != get_interface_mtu($mtuif)) {
3354 c399d0dd Renato Botelho
			if (isset($config['laggs']['lagg']) && is_array($config['laggs']['lagg'])) {
3355
				foreach ($config['laggs']['lagg'] as $lagg) {
3356 60e15be2 David Wood
					if ($lagg['laggif'] == $mtuif) {
3357 c399d0dd Renato Botelho
						interface_lagg_configure($lagg);
3358
						break;
3359 71c26c22 Renato Botelho
					}
3360
				}
3361
			}
3362 c399d0dd Renato Botelho
		}
3363
	} else {
3364 60e15be2 David Wood
		if ($wantedmtu != get_interface_mtu($mtuif)) {
3365
			pfSense_interface_mtu($mtuif, $wantedmtu);
3366 c399d0dd Renato Botelho
		}
3367 3f3252f6 Renato Botelho
	}
3368 c399d0dd Renato Botelho
	/* XXX: What about gre/gif/.. ? */
3369 4a735210 Renato Botelho
3370 89c8934f Luiz Otavio O Souza
	if (does_interface_exist($wancfg['if'])) {
3371
		interfaces_bring_up($wancfg['if']);
3372
	}
3373
3374 afb38815 Ermal LUÇI
	switch ($wancfg['ipaddr']) {
3375 cf73302f Phil Davis
		case 'dhcp':
3376
			interface_dhcp_configure($interface);
3377
			break;
3378
		case 'pppoe':
3379
		case 'l2tp':
3380
		case 'pptp':
3381
		case 'ppp':
3382
			interface_ppps_configure($interface);
3383
			break;
3384
		default:
3385
			/* XXX: Kludge for now related to #3280 */
3386
			if (!in_array($tunnelif, array("gif", "gre", "ovp"))) {
3387
				if (is_ipaddrv4($wancfg['ipaddr']) && $wancfg['subnet'] <> "") {
3388
					pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
3389
				}
3390
			}
3391
			break;
3392 afb38815 Ermal LUÇI
	}
3393
3394
	switch ($wancfg['ipaddrv6']) {
3395 cf73302f Phil Davis
		case 'slaac':
3396
		case 'dhcp6':
3397 0c9b98c0 Chris Buechler
			// N.B. PPP connections using PPP as the IPv6 parent interface are excluded because the ppp-ipv6 script
3398
			// calls interface_dhcpv6_configure() for these connections after IPv6CP is up, whilst rc.newwanip
3399
			// handles all non-PPP connections with 'dhcp6usev4iface' set
3400
			if (!(isset($wancfg['dhcp6usev4iface']) || $wancfg['ipaddr']==='ppp')) {
3401
				interface_dhcpv6_configure($interface, $wancfg);
3402
			}
3403 cf73302f Phil Davis
			break;
3404
		case '6rd':
3405
			interface_6rd_configure($interface, $wancfg);
3406
			break;
3407
		case '6to4':
3408
			interface_6to4_configure($interface, $wancfg);
3409
			break;
3410
		case 'track6':
3411
			interface_track6_configure($interface, $wancfg, $linkupevent);
3412
			break;
3413
		default:
3414
			/* XXX: Kludge for now related to #3280 */
3415
			if (!in_array($tunnelif, array("gif", "gre", "ovp"))) {
3416
				if (is_ipaddrv6($wancfg['ipaddrv6']) && $wancfg['subnetv6'] <> "") {
3417
					//pfSense_interface_setaddress($realif, "{$wancfg['ipaddrv6']}/{$wancfg['subnetv6']}");
3418
					// FIXME: Add IPv6 Support to the pfSense module
3419
					mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$wancfg['ipaddrv6']} prefixlen " . escapeshellarg($wancfg['subnetv6']));
3420
				}
3421
			}
3422
			break;
3423 afb38815 Ermal LUÇI
	}
3424 67b057a9 Ermal
3425
	interface_netgraph_needed($interface);
3426 be45aa79 Renato Botelho
3427 285ef132 Ermal LUÇI
	if (!platform_booting()) {
3428 dcadda55 Ermal
		link_interface_to_vips($interface, "update");
3429 6991dcb1 Ermal
3430 7de6a47f Ermal LUÇI
		if ($tunnelif != 'gre') {
3431
			unset($gre);
3432
			$gre = link_interface_to_gre($interface);
3433 cf73302f Phil Davis
			if (!empty($gre)) {
3434 7de6a47f Ermal LUÇI
				array_walk($gre, 'interface_gre_configure');
3435 cf73302f Phil Davis
			}
3436 7de6a47f Ermal LUÇI
		}
3437
3438
		if ($tunnelif != 'gif') {
3439
			unset($gif);
3440 cf73302f Phil Davis
			$gif = link_interface_to_gif ($interface);
3441
			if (!empty($gif)) {
3442 7de6a47f Ermal LUÇI
				array_walk($gif, 'interface_gif_configure');
3443 cf73302f Phil Davis
			}
3444 7de6a47f Ermal LUÇI
		}
3445 a639bb91 Ermal
3446 bf17eb72 Ermal
		if ($linkupevent == false || substr($realif, 0, 4) == "ovpn") {
3447 7413cbfd Ermal
			unset($bridgetmp);
3448
			$bridgetmp = link_interface_to_bridge($interface);
3449 cf73302f Phil Davis
			if (!empty($bridgetmp)) {
3450 7413cbfd Ermal
				interface_bridge_add_member($bridgetmp, $realif);
3451 cf73302f Phil Davis
			}
3452 7413cbfd Ermal
		}
3453 ccbd2447 Ermal Luçi
3454 48f23632 Ermal
		$grouptmp = link_interface_to_group($interface);
3455 cf73302f Phil Davis
		if (!empty($grouptmp)) {
3456 ed62880b Ermal
			array_walk($grouptmp, 'interface_group_add_member');
3457 cf73302f Phil Davis
		}
3458 48f23632 Ermal
3459 cf73302f Phil Davis
		if ($interface == "lan") {
3460 4476d447 Ermal Luçi
			/* make new hosts file */
3461 ffeb5acf Scott Ullrich
			system_hosts_generate();
3462 cf73302f Phil Davis
		}
3463 4476d447 Ermal Luçi
3464 a5d6f60b Ermal Lu?i
		if ($reloadall == true) {
3465 cfc707f7 Scott Ullrich
3466 a5d6f60b Ermal Lu?i
			/* reconfigure static routes (kernel may have deleted them) */
3467 1ea67f2e Ermal
			system_routing_configure($interface);
3468 cfc707f7 Scott Ullrich
3469 a5d6f60b Ermal Lu?i
			/* reload ipsec tunnels */
3470 b2448aa0 Ermal LUÇI
			send_event("service reload ipsecdns");
3471 cfc707f7 Scott Ullrich
3472 cf73302f Phil Davis
			if (isset($config['dnsmasq']['enable'])) {
3473 9a51bb64 Warren Baker
				services_dnsmasq_configure();
3474 361b388b k-paulius
			}
3475
3476
			if (isset($config['unbound']['enable'])) {
3477 9a51bb64 Warren Baker
				services_unbound_configure();
3478 cf73302f Phil Davis
			}
3479 b5eeef07 Ermal
3480 a5d6f60b Ermal Lu?i
			/* update dyndns */
3481 422bc2a7 Ermal
			send_event("service reload dyndns {$interface}");
3482 a23d7248 Scott Ullrich
3483 a5d6f60b Ermal Lu?i
			/* reload captive portal */
3484 cf73302f Phil Davis
			if (!function_exists('captiveportal_init_rules_byinterface')) {
3485 a08db603 Ermal LUÇI
				require_once('captiveportal.inc');
3486 cf73302f Phil Davis
			}
3487 a08db603 Ermal LUÇI
			captiveportal_init_rules_byinterface($interface);
3488 a5d6f60b Ermal Lu?i
		}
3489 5b237745 Scott Ullrich
	}
3490 cfc707f7 Scott Ullrich
3491 c1d8c235 Renato Botelho
	interfaces_staticarp_configure($interface);
3492 5b237745 Scott Ullrich
	return 0;
3493
}
3494
3495 b67e9e62 Ermal
function interface_track6_configure($interface = "lan", $wancfg, $linkupevent = false) {
3496 20a7cb15 smos
	global $config, $g;
3497
3498 cf73302f Phil Davis
	if (!is_array($wancfg)) {
3499 7a04cd20 Ermal
		return;
3500 cf73302f Phil Davis
	}
3501 7a04cd20 Ermal
3502 cf73302f Phil Davis
	if (!isset($wancfg['enable'])) {
3503 b0059636 Ermal
		return;
3504 cf73302f Phil Davis
	}
3505 be45aa79 Renato Botelho
3506 20a7cb15 smos
	/* If the interface is not configured via another, exit */
3507 cf73302f Phil Davis
	if (empty($wancfg['track6-interface'])) {
3508 b0059636 Ermal
		return;
3509 cf73302f Phil Davis
	}
3510 20a7cb15 smos
3511 e90c833a smos
	/* always configure a link-local of fe80::1:1 on the track6 interfaces */
3512
	$realif = get_real_interface($interface);
3513 bfa8df8a k-paulius
	$linklocal = find_interface_ipv6_ll($realif, true);
3514
	if (!empty($linklocal) && $linklocal != "fe80::1:1%{$realif}") {
3515 919ff1f0 Ermal
		mwexec("/sbin/ifconfig {$realif} inet6 {$linklocal} delete");
3516 cf73302f Phil Davis
	}
3517 55909a9a Ermal
	/* XXX: This might break for good on a carp installation using link-local as network ips */
3518
	/* XXX: Probably should remove? */
3519 e90c833a smos
	mwexec("/sbin/ifconfig {$realif} inet6 fe80::1:1%{$realif}");
3520
3521 7a04cd20 Ermal
	$trackcfg = $config['interfaces'][$wancfg['track6-interface']];
3522
	if (!isset($trackcfg['enable'])) {
3523 223ebd3f Chris Buechler
		log_error(sprintf(gettext('Interface %1$s tracking non-existent interface %2$s'), $interface, $wancfg['track6-interface']));
3524 7a04cd20 Ermal
		return;
3525
	}
3526
3527 086cf944 Phil Davis
	switch ($trackcfg['ipaddrv6']) {
3528 cf73302f Phil Davis
		case "6to4":
3529
			if ($g['debug']) {
3530 d18f3f6e Phil Davis
				log_error(sprintf(gettext('Interface %1$s configured via %2$s type %3$s'), $interface, $wancfg['track6-interface'], $type));
3531 cf73302f Phil Davis
			}
3532
			interface_track6_6to4_configure($interface, $wancfg);
3533
			break;
3534
		case "6rd":
3535
			if ($g['debug']) {
3536 d18f3f6e Phil Davis
				log_error(sprintf(gettext('Interface %1$s configured via %2$s type %3$s'), $interface, $wancfg['track6-interface'], $type));
3537 cf73302f Phil Davis
			}
3538
			interface_track6_6rd_configure($interface, $wancfg);
3539
			break;
3540
		case "dhcp6":
3541 12d7d9e7 Chris Buechler
			if ($linkupevent == true) {
3542
				/*
3543
				 * NOTE: Usually come here from rc.linkup calling so just call directly instead of generating event
3544
				 * 	Instead of disrupting all other v4 configuration just restart DHCPv6 client for now
3545
				 *
3546
				 * XXX: Probably DHCPv6 client should handle this automagically itself?
3547
				 */
3548
				$parentrealif = get_real_interface($wancfg['track6-interface']);
3549
				$pidv6 = find_dhcp6c_process($parentrealif);
3550
				if ($pidv6) {
3551
					posix_kill($pidv6, SIGHUP);
3552
				}
3553 cf73302f Phil Davis
			}
3554
			break;
3555 20a7cb15 smos
	}
3556 b0059636 Ermal
3557 b460c43b Chris Buechler
	if ($linkupevent == false && !platform_booting()) {
3558 cf73302f Phil Davis
		if (!function_exists('services_dhcpd_configure')) {
3559 7fd67662 Ermal
			require_once("services.inc");
3560 cf73302f Phil Davis
		}
3561 6387590f Ermal
3562 1e0d9c89 NewEraCracker
		/* restart dns servers (defering dhcpd reload) */
3563 cf73302f Phil Davis
		if (isset($config['unbound']['enable'])) {
3564 1e0d9c89 NewEraCracker
			services_unbound_configure(false);
3565 cf73302f Phil Davis
		}
3566 b460c43b Chris Buechler
		if (isset($config['dnsmasq']['enable'])) {
3567 1e0d9c89 NewEraCracker
			services_dnsmasq_configure(false);
3568 b460c43b Chris Buechler
		}
3569
3570 1e0d9c89 NewEraCracker
		/* reconfigure dhcpdv6 (leaving dhcpdv4 alone) */
3571 7fd67662 Ermal
		services_dhcpd_configure("inet6");
3572
	}
3573 6387590f Ermal
3574 20a7cb15 smos
	return 0;
3575
}
3576
3577 7a04cd20 Ermal
function interface_track6_6rd_configure($interface = "lan", $lancfg) {
3578 20a7cb15 smos
	global $config, $g;
3579 da9dd1b4 Ermal
	global $interface_ipv6_arr_cache;
3580 a8f5790a Renato Botelho
	global $interface_snv6_arr_cache;
3581 20a7cb15 smos
3582 cf73302f Phil Davis
	if (!is_array($lancfg)) {
3583 b0059636 Ermal
		return;
3584 cf73302f Phil Davis
	}
3585 be45aa79 Renato Botelho
3586 20a7cb15 smos
	/* If the interface is not configured via another, exit */
3587 cf73302f Phil Davis
	if (empty($lancfg['track6-interface'])) {
3588 b0059636 Ermal
		return;
3589 cf73302f Phil Davis
	}
3590 b0059636 Ermal
3591 20a7cb15 smos
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
3592 7a04cd20 Ermal
	if (empty($wancfg)) {
3593 223ebd3f Chris Buechler
		log_error(sprintf(gettext('Interface %1$s tracking non-existent interface %2$s'), $interface, $lancfg['track6-interface']));
3594 b0059636 Ermal
		return;
3595 7a04cd20 Ermal
	}
3596 be45aa79 Renato Botelho
3597 ff5674dc Ermal
	$ip4address = get_interface_ip($lancfg['track6-interface']);
3598 7a04cd20 Ermal
	if (!is_ipaddrv4($ip4address)) { /* XXX: This should not be needed by 6rd || (is_private_ip($ip4address))) { */
3599 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']));
3600 b0059636 Ermal
		return;
3601 20a7cb15 smos
	}
3602
	$hexwanv4 = return_hex_ipv4($ip4address);
3603 be45aa79 Renato Botelho
3604 20a7cb15 smos
	/* create the long prefix notation for math, save the prefix length */
3605
	$rd6prefix = explode("/", $wancfg['prefix-6rd']);
3606
	$rd6prefixlen = $rd6prefix[1];
3607
	$rd6prefix = Net_IPv6::uncompress($rd6prefix[0]);
3608
3609
	/* binary presentation of the prefix for all 128 bits. */
3610
	$rd6lanbin = convert_ipv6_to_128bit($rd6prefix);
3611 be45aa79 Renato Botelho
3612 20a7cb15 smos
	/* just save the left prefix length bits */
3613
	$rd6lanbin = substr($rd6lanbin, 0, $rd6prefixlen);
3614
	/* add the v4 address, offset n bits from the left */
3615
	$rd6lanbin .= substr(sprintf("%032b", hexdec($hexwanv4)), (0 + $wancfg['prefix-6rd-v4plen']), 32);
3616
3617
	/* add the custom prefix id, max 32bits long? (64 bits - (prefixlen + (32 - v4plen)) */
3618
	/* 64 - (37 + (32 - 17)) = 8 == /52 */
3619
	$restbits = 64 - ($rd6prefixlen + (32 - $wancfg['prefix-6rd-v4plen']));
3620
	// echo "64 - (prefixlen {$rd6prefixlen} + v4len (32 - {$wancfg['prefix-6rd-v4plen']})) = {$restbits} \n";
3621
	$rd6lanbin .= substr(sprintf("%032b", str_pad($lancfg['track6-prefix-id'], 32, "0", STR_PAD_LEFT)), (32 - $restbits), 32);
3622
	/* fill the rest out with zeros */
3623 91f026b0 ayvis
	$rd6lanbin = str_pad($rd6lanbin, 128, "0", STR_PAD_RIGHT);
3624 20a7cb15 smos
3625 be45aa79 Renato Botelho
	/* convert the 128 bits for the lan address back into a valid IPv6 address */
3626 20a7cb15 smos
	$rd6lan = convert_128bit_to_ipv6($rd6lanbin) ."1";
3627 be45aa79 Renato Botelho
3628 b0059636 Ermal
	$lanif = get_real_interface($interface);
3629 c4fc2eae Ermal
	$oip = find_interface_ipv6($lanif);
3630 cf73302f Phil Davis
	if (is_ipaddrv6($oip)) {
3631 c4fc2eae Ermal
		mwexec("/sbin/ifconfig {$lanif} inet6 {$oip} delete");
3632 cf73302f Phil Davis
	}
3633 da9dd1b4 Ermal
	unset($interface_ipv6_arr_cache[$lanif]);
3634
	unset($interface_snv6_arr_cache[$lanif]);
3635 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));
3636 20a7cb15 smos
	mwexec("/sbin/ifconfig {$lanif} inet6 {$rd6lan} prefixlen 64");
3637 b0059636 Ermal
3638 20a7cb15 smos
	return 0;
3639
}
3640
3641 7a04cd20 Ermal
function interface_track6_6to4_configure($interface = "lan", $lancfg) {
3642 20a7cb15 smos
	global $config, $g;
3643 da9dd1b4 Ermal
	global $interface_ipv6_arr_cache;
3644 a8f5790a Renato Botelho
	global $interface_snv6_arr_cache;
3645 20a7cb15 smos
3646 cf73302f Phil Davis
	if (!is_array($lancfg)) {
3647 b0059636 Ermal
		return;
3648 cf73302f Phil Davis
	}
3649 be45aa79 Renato Botelho
3650 20a7cb15 smos
	/* If the interface is not configured via another, exit */
3651 cf73302f Phil Davis
	if (empty($lancfg['track6-interface'])) {
3652 b0059636 Ermal
		return;
3653 cf73302f Phil Davis
	}
3654 b0059636 Ermal
3655 7a04cd20 Ermal
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
3656
	if (empty($wancfg)) {
3657 223ebd3f Chris Buechler
		log_error(sprintf(gettext('Interface %1$s tracking non-existent interface %2$s'), $interface, $lancfg['track6-interface']));
3658 7a04cd20 Ermal
		return;
3659
	}
3660
3661 ff5674dc Ermal
	$ip4address = get_interface_ip($lancfg['track6-interface']);
3662 b0059636 Ermal
	if (!is_ipaddrv4($ip4address) || is_private_ip($ip4address)) {
3663 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']));
3664 b0059636 Ermal
		return;
3665 20a7cb15 smos
	}
3666
	$hexwanv4 = return_hex_ipv4($ip4address);
3667 be45aa79 Renato Botelho
3668 20a7cb15 smos
	/* create the long prefix notation for math, save the prefix length */
3669
	$sixto4prefix = "2002::";
3670
	$sixto4prefixlen = 16;
3671
	$sixto4prefix = Net_IPv6::uncompress($sixto4prefix);
3672
3673
	/* binary presentation of the prefix for all 128 bits. */
3674
	$sixto4lanbin = convert_ipv6_to_128bit($sixto4prefix);
3675 be45aa79 Renato Botelho
3676 20a7cb15 smos
	/* just save the left prefix length bits */
3677
	$sixto4lanbin = substr($sixto4lanbin, 0, $sixto4prefixlen);
3678
	/* add the v4 address */
3679
	$sixto4lanbin .= sprintf("%032b", hexdec($hexwanv4));
3680
	/* add the custom prefix id */
3681
	$sixto4lanbin .= sprintf("%016b", $lancfg['track6-prefix-id']);
3682
	/* fill the rest out with zeros */
3683 91f026b0 ayvis
	$sixto4lanbin = str_pad($sixto4lanbin, 128, "0", STR_PAD_RIGHT);
3684 be45aa79 Renato Botelho
3685
	/* convert the 128 bits for the lan address back into a valid IPv6 address */
3686 20a7cb15 smos
	$sixto4lan = convert_128bit_to_ipv6($sixto4lanbin) ."1";
3687 be45aa79 Renato Botelho
3688 b0059636 Ermal
	$lanif = get_real_interface($interface);
3689 c4fc2eae Ermal
	$oip = find_interface_ipv6($lanif);
3690 cf73302f Phil Davis
	if (is_ipaddrv6($oip)) {
3691 c4fc2eae Ermal
		mwexec("/sbin/ifconfig {$lanif} inet6 {$oip} delete");
3692 cf73302f Phil Davis
	}
3693 da9dd1b4 Ermal
	unset($interface_ipv6_arr_cache[$lanif]);
3694
	unset($interface_snv6_arr_cache[$lanif]);
3695 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));
3696 20a7cb15 smos
	mwexec("/sbin/ifconfig {$lanif} inet6 {$sixto4lan} prefixlen 64");
3697 b0059636 Ermal
3698 20a7cb15 smos
	return 0;
3699
}
3700
3701 7a04cd20 Ermal
function interface_6rd_configure($interface = "wan", $wancfg) {
3702 668e8961 smos
	global $config, $g;
3703
3704 be45aa79 Renato Botelho
	/* because this is a tunnel interface we can only function
3705 668e8961 smos
	 *	with a public IPv4 address on the interface */
3706
3707 cf73302f Phil Davis
	if (!is_array($wancfg)) {
3708 b0059636 Ermal
		return;
3709 cf73302f Phil Davis
	}
3710 668e8961 smos
3711 cf73302f Phil Davis
	if (!is_module_loaded('if_stf.ko')) {
3712 ebafd470 Ermal
		mwexec('/sbin/kldload if_stf.ko');
3713 cf73302f Phil Davis
	}
3714 ebafd470 Ermal
3715 668e8961 smos
	$wanif = get_real_interface($interface);
3716
	$ip4address = find_interface_ip($wanif);
3717 5d697e08 Ermal
	if (!is_ipaddrv4($ip4address)) {
3718 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));
3719 1f78ab3a smos
		return false;
3720 668e8961 smos
	}
3721 20a7cb15 smos
	$hexwanv4 = return_hex_ipv4($ip4address);
3722 be45aa79 Renato Botelho
3723 cf73302f Phil Davis
	if (!is_numeric($wancfg['prefix-6rd-v4plen'])) {
3724 20a7cb15 smos
		$wancfg['prefix-6rd-v4plen'] = 0;
3725 cf73302f Phil Davis
	}
3726 668e8961 smos
3727 51c57aae smos
	/* create the long prefix notation for math, save the prefix length */
3728 f87ccbed smos
	$rd6prefix = explode("/", $wancfg['prefix-6rd']);
3729
	$rd6prefixlen = $rd6prefix[1];
3730 f233ddeb Ermal
	$brgw = explode('.', $wancfg['gateway-6rd']);
3731 5e964cfd Ermal LUÇI
	$rd6brgw = substr(Net_IPv6::_ip2Bin($rd6prefix[0]), 0, $rd6prefixlen);
3732
	$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);
3733 cf73302f Phil Davis
	if (strlen($rd6brgw) < 128) {
3734 5e964cfd Ermal LUÇI
		$rd6brgw = str_pad($rd6brgw, 128, '0', STR_PAD_RIGHT);
3735 cf73302f Phil Davis
	}
3736 5e964cfd Ermal LUÇI
	$rd6brgw = Net_IPv6::compress(Net_IPv6::_bin2Ip($rd6brgw));
3737 f233ddeb Ermal
	unset($brgw);
3738 f87ccbed smos
	$rd6prefix = Net_IPv6::uncompress($rd6prefix[0]);
3739 51c57aae smos
3740
	/* binary presentation of the prefix for all 128 bits. */
3741 20a7cb15 smos
	$rd6prefixbin = convert_ipv6_to_128bit($rd6prefix);
3742 be45aa79 Renato Botelho
3743 51c57aae smos
	/* just save the left prefix length bits */
3744 20a7cb15 smos
	$rd6prefixbin = substr($rd6prefixbin, 0, $rd6prefixlen);
3745 51c57aae smos
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3746 4aa569bd smos
	$rd6prefixbin .= substr(sprintf("%032b", hexdec($hexwanv4)), $wancfg['prefix-6rd-v4plen'], 32);
3747 20a7cb15 smos
	/* fill out the rest with 0's */
3748 91f026b0 ayvis
	$rd6prefixbin = str_pad($rd6prefixbin, 128, "0", STR_PAD_RIGHT);
3749 51c57aae smos
3750 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3751 4aa569bd smos
	$rd6prefix = convert_128bit_to_ipv6($rd6prefixbin);
3752 f87ccbed smos
3753 733c6f89 Ermal
3754 7d1f2eac Ermal
	/* XXX: need to extend to support variable prefix size for v4 */
3755 cf73302f Phil Davis
	if (!is_module_loaded("if_stf")) {
3756 b686e5d0 Ermal
		mwexec("/sbin/kldload if_stf.ko");
3757 cf73302f Phil Davis
	}
3758 7d1f2eac Ermal
	$stfiface = "{$interface}_stf";
3759 cf73302f Phil Davis
	if (does_interface_exist($stfiface)) {
3760 c4fc2eae Ermal
		pfSense_interface_destroy($stfiface);
3761 cf73302f Phil Davis
	}
3762 c4fc2eae Ermal
	$tmpstfiface = pfSense_interface_create("stf");
3763
	pfSense_interface_rename($tmpstfiface, $stfiface);
3764 7d1f2eac Ermal
	pfSense_interface_flags($stfiface, IFF_LINK2);
3765
	mwexec("/sbin/ifconfig {$stfiface} inet6 {$rd6prefix}/{$rd6prefixlen}");
3766 f0f714c5 Ermal
	mwexec("/sbin/ifconfig {$stfiface} stfv4br " . escapeshellarg($wancfg['gateway-6rd']));
3767 cf73302f Phil Davis
	if ($wancfg['prefix-6rd-v4plen'] >= 0 && $wancfg['prefix-6rd-v4plen'] <= 32) {
3768 5d697e08 Ermal
		mwexec("/sbin/ifconfig {$stfiface} stfv4net {$ip4address}/" . escapeshellarg($wancfg['prefix-6rd-v4plen']));
3769 cf73302f Phil Davis
	}
3770
	if ($g['debug']) {
3771 7d1f2eac Ermal
		log_error("Created 6rd interface {$stfiface} {$rd6prefix}/{$rd6prefixlen}");
3772 cf73302f Phil Davis
	}
3773 668e8961 smos
3774 f55b6cbb smos
	/* write out a default router file */
3775 20a7cb15 smos
	file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$rd6brgw}\n");
3776
	file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$rd6brgw}\n");
3777 2d5ca06e smos
3778 5ee79d32 Ermal
	$ip4gateway = get_interface_gateway($interface);
3779 cf73302f Phil Davis
	if (is_ipaddrv4($ip4gateway)) {
3780 87dfd826 Ermal
		mwexec("/sbin/route change -host " . escapeshellarg($wancfg['gateway-6rd']) . " {$ip4gateway}");
3781 cf73302f Phil Davis
	}
3782 c8ed8142 smos
3783 2d5ca06e smos
	/* configure dependent interfaces */
3784 cf73302f Phil Davis
	if (!platform_booting()) {
3785 7a04cd20 Ermal
		link_interface_to_track6($interface, "update");
3786 cf73302f Phil Davis
	}
3787 66c73aab Ermal
3788 f55b6cbb smos
	return 0;
3789 668e8961 smos
}
3790
3791 cf73302f Phil Davis
function interface_6to4_configure($interface = "wan", $wancfg) {
3792 31c43fd3 smos
	global $config, $g;
3793
3794 be45aa79 Renato Botelho
	/* because this is a tunnel interface we can only function
3795 31c43fd3 smos
	 *	with a public IPv4 address on the interface */
3796
3797 cf73302f Phil Davis
	if (!is_array($wancfg)) {
3798 7a04cd20 Ermal
		return;
3799 cf73302f Phil Davis
	}
3800 31c43fd3 smos
3801
	$wanif = get_real_interface($interface);
3802
	$ip4address = find_interface_ip($wanif);
3803 cf73302f Phil Davis
	if ((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
3804 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));
3805 31c43fd3 smos
		return false;
3806
	}
3807 be45aa79 Renato Botelho
3808 31c43fd3 smos
	/* create the long prefix notation for math, save the prefix length */
3809
	$stfprefixlen = 16;
3810
	$stfprefix = Net_IPv6::uncompress("2002::");
3811
	$stfarr = explode(":", $stfprefix);
3812
	$v4prefixlen = "0";
3813 be45aa79 Renato Botelho
3814 31c43fd3 smos
	/* we need the hex form of the interface IPv4 address */
3815
	$ip4arr = explode(".", $ip4address);
3816
	$hexwanv4 = "";
3817 cf73302f Phil Davis
	foreach ($ip4arr as $octet) {
3818 31c43fd3 smos
		$hexwanv4 .= sprintf("%02x", $octet);
3819 cf73302f Phil Davis
	}
3820 31c43fd3 smos
3821
	/* we need the hex form of the broker IPv4 address */
3822
	$ip4arr = explode(".", "192.88.99.1");
3823
	$hexbrv4 = "";
3824 cf73302f Phil Davis
	foreach ($ip4arr as $octet) {
3825 31c43fd3 smos
		$hexbrv4 .= sprintf("%02x", $octet);
3826 cf73302f Phil Davis
	}
3827 be45aa79 Renato Botelho
3828 31c43fd3 smos
	/* binary presentation of the prefix for all 128 bits. */
3829
	$stfprefixbin = "";
3830 cf73302f Phil Davis
	foreach ($stfarr as $element) {
3831 31c43fd3 smos
		$stfprefixbin .= sprintf("%016b", hexdec($element));
3832
	}
3833
	/* just save the left prefix length bits */
3834
	$stfprefixstartbin = substr($stfprefixbin, 0, $stfprefixlen);
3835
3836
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3837
	$stfbrokerbin = substr(sprintf("%032b", hexdec($hexbrv4)), $v4prefixlen, 32);
3838 91f026b0 ayvis
	$stfbrokerbin = str_pad($stfprefixstartbin . $stfbrokerbin, 128, "0", STR_PAD_RIGHT);
3839 31c43fd3 smos
3840
	/* for the local subnet too. */
3841
	$stflanbin = substr(sprintf("%032b", hexdec($hexwanv4)), $v4prefixlen, 32);
3842 91f026b0 ayvis
	$stflanbin = str_pad($stfprefixstartbin . $stflanbin, 128, "0", STR_PAD_RIGHT);
3843 31c43fd3 smos
3844 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3845 31c43fd3 smos
	$stfbrarr = array();
3846
	$stfbrbinarr = array();
3847
	$stfbrbinarr = str_split($stfbrokerbin, 16);
3848 cf73302f Phil Davis
	foreach ($stfbrbinarr as $bin) {
3849 31c43fd3 smos
		$stfbrarr[] = dechex(bindec($bin));
3850 cf73302f Phil Davis
	}
3851 31c43fd3 smos
	$stfbrgw = Net_IPv6::compress(implode(":", $stfbrarr));
3852
3853 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3854 31c43fd3 smos
	$stflanarr = array();
3855
	$stflanbinarr = array();
3856
	$stflanbinarr = str_split($stflanbin, 16);
3857 cf73302f Phil Davis
	foreach ($stflanbinarr as $bin) {
3858 31c43fd3 smos
		$stflanarr[] = dechex(bindec($bin));
3859 cf73302f Phil Davis
	}
3860 31c43fd3 smos
	$stflanpr = Net_IPv6::compress(implode(":", $stflanarr));
3861
	$stflanarr[7] = 1;
3862
	$stflan = Net_IPv6::compress(implode(":", $stflanarr));
3863
3864
	/* setup the stf interface */
3865 cf73302f Phil Davis
	if (!is_module_loaded("if_stf")) {
3866 b686e5d0 Ermal
		mwexec("/sbin/kldload if_stf.ko");
3867 cf73302f Phil Davis
	}
3868 7d1f2eac Ermal
	$stfiface = "{$interface}_stf";
3869 cf73302f Phil Davis
	if (does_interface_exist($stfiface)) {
3870 c4fc2eae Ermal
		pfSense_interface_destroy($stfiface);
3871 cf73302f Phil Davis
	}
3872 c4fc2eae Ermal
	$tmpstfiface = pfSense_interface_create("stf");
3873
	pfSense_interface_rename($tmpstfiface, $stfiface);
3874 7d1f2eac Ermal
	pfSense_interface_flags($stfiface, IFF_LINK2);
3875
	mwexec("/sbin/ifconfig {$stfiface} inet6 {$stflanpr} prefixlen 16");
3876 31c43fd3 smos
3877 cf73302f Phil Davis
	if ($g['debug']) {
3878 7d1f2eac Ermal
		log_error("Set IPv6 address inet6 {$stflanpr} prefixlen 16 for {$stfiface}, route {$stfbrgw}");
3879 cf73302f Phil Davis
	}
3880 be45aa79 Renato Botelho
3881 31c43fd3 smos
	/* write out a default router file */
3882
	file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$stfbrgw}");
3883
	file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$stfbrgw}");
3884 2d5ca06e smos
3885 5ee79d32 Ermal
	$ip4gateway = get_interface_gateway($interface);
3886 cf73302f Phil Davis
	if (is_ipaddrv4($ip4gateway)) {
3887 59b99089 Ermal
		mwexec("/sbin/route change -host 192.88.99.1 {$ip4gateway}");
3888 cf73302f Phil Davis
	}
3889 c8ed8142 smos
3890 cf73302f Phil Davis
	if (!platform_booting()) {
3891 7a04cd20 Ermal
		link_interface_to_track6($interface, "update");
3892 cf73302f Phil Davis
	}
3893 be45aa79 Renato Botelho
3894 31c43fd3 smos
	return 0;
3895
}
3896
3897 7a04cd20 Ermal
function interface_dhcpv6_configure($interface = "wan", $wancfg) {
3898 ed395640 Seth Mos
	global $config, $g;
3899
3900 cf73302f Phil Davis
	if (!is_array($wancfg)) {
3901 b0059636 Ermal
		return;
3902 cf73302f Phil Davis
	}
3903 ed395640 Seth Mos
3904 06886ae3 Ermal
	$wanif = get_real_interface($interface, "inet6");
3905 d53a9a51 smos
	$dhcp6cconf = "";
3906 dd5d1a24 k-paulius
3907
	if ($wancfg['adv_dhcp6_config_file_override']) {
3908
		// DHCP6 Config File Override
3909
		$dhcp6cconf = DHCP6_Config_File_Override($wancfg, $wanif);
3910
	} elseif ($wancfg['adv_dhcp6_config_advanced']) {
3911
		// DHCP6 Config File Advanced
3912
		$dhcp6cconf = DHCP6_Config_File_Advanced($interface, $wancfg, $wanif);
3913 d53a9a51 smos
	} else {
3914 dd5d1a24 k-paulius
		// DHCP6 Config File Basic
3915
		$dhcp6cconf .= "interface {$wanif} {\n";
3916
3917
		/* for SLAAC interfaces we do fire off a dhcp6 client for just our name servers */
3918
		if ($wancfg['ipaddrv6'] == "slaac") {
3919 ddd1f864 k-paulius
			$dhcp6cconf .= "\tinformation-only;\n";
3920
			$dhcp6cconf .= "\trequest domain-name-servers;\n";
3921
			$dhcp6cconf .= "\trequest domain-name;\n";
3922
			$dhcp6cconf .= "\tscript \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n";
3923 dd5d1a24 k-paulius
			$dhcp6cconf .= "};\n";
3924
		} else {
3925
			$trackiflist = array();
3926
			$iflist = link_interface_to_track6($interface);
3927
			foreach ($iflist as $ifname => $ifcfg) {
3928
				if (is_numeric($ifcfg['track6-prefix-id'])) {
3929
					$trackiflist[$ifname] = $ifcfg;
3930
				}
3931 cf73302f Phil Davis
			}
3932 a13acc0e smos
3933 dd5d1a24 k-paulius
			/* skip address request if this is set */
3934
			if (!isset($wancfg['dhcp6prefixonly'])) {
3935 ddd1f864 k-paulius
				$dhcp6cconf .= "\tsend ia-na 0;\t# request stateful address\n";
3936 dd5d1a24 k-paulius
			}
3937
			if (is_numeric($wancfg['dhcp6-ia-pd-len']) && !empty($trackiflist)) {
3938 ddd1f864 k-paulius
				$dhcp6cconf .= "\tsend ia-pd 0;\t# request prefix delegation\n";
3939 dd5d1a24 k-paulius
			}
3940 d53a9a51 smos
3941 dd5d1a24 k-paulius
			$dhcp6cconf .= "\trequest domain-name-servers;\n";
3942
			$dhcp6cconf .= "\trequest domain-name;\n";
3943
			$dhcp6cconf .= "\tscript \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n";
3944
			$dhcp6cconf .= "};\n";
3945 a13acc0e smos
3946 dd5d1a24 k-paulius
			if (!isset($wancfg['dhcp6prefixonly'])) {
3947
				$dhcp6cconf .= "id-assoc na 0 { };\n";
3948 cf73302f Phil Davis
			}
3949 dd5d1a24 k-paulius
3950
			if (is_numeric($wancfg['dhcp6-ia-pd-len']) && !empty($trackiflist)) {
3951
				/* Setup the prefix delegation */
3952
				$dhcp6cconf .= "id-assoc pd 0 {\n";
3953
				$preflen = 64 - $wancfg['dhcp6-ia-pd-len'];
3954
				if (isset($wancfg['dhcp6-ia-pd-send-hint'])) {
3955 ddd1f864 k-paulius
					$dhcp6cconf .= "\tprefix ::/{$preflen} infinity;\n";
3956 cf73302f Phil Davis
				}
3957 dd5d1a24 k-paulius
				foreach ($trackiflist as $friendly => $ifcfg) {
3958
					if ($g['debug']) {
3959
						log_error("setting up $ifdescr - {$ifcfg['track6-prefix-id']}");
3960
					}
3961
					$realif = get_real_interface($friendly);
3962 ddd1f864 k-paulius
					$dhcp6cconf .= "\tprefix-interface {$realif} {\n";
3963
					$dhcp6cconf .= "\t\tsla-id {$ifcfg['track6-prefix-id']};\n";
3964
					$dhcp6cconf .= "\t\tsla-len {$wancfg['dhcp6-ia-pd-len']};\n";
3965
					$dhcp6cconf .= "\t};\n";
3966 dd5d1a24 k-paulius
				}
3967
				unset($preflen, $iflist, $ifcfg, $ifname);
3968
				$dhcp6cconf .= "};\n";
3969 d53a9a51 smos
			}
3970 dd5d1a24 k-paulius
			unset($trackiflist);
3971 d53a9a51 smos
		}
3972 cf73302f Phil Davis
	}
3973 f4dd8b4c N0YB
3974 b0059636 Ermal
	/* wide-dhcp6c works for now. */
3975
	if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}.conf", $dhcp6cconf)) {
3976
		printf("Error: cannot open dhcp6c_{$interface}.conf in interface_dhcpv6_configure() for writing.\n");
3977 d12ae241 Renato Botelho
		unset($dhcp6cconf);
3978 b0059636 Ermal
		return 1;
3979
	}
3980 d12ae241 Renato Botelho
	unset($dhcp6cconf);
3981 ed395640 Seth Mos
3982 b0059636 Ermal
	$dhcp6cscript = "#!/bin/sh\n";
3983
	$dhcp6cscript .= "# This shell script launches /etc/rc.newwanipv6 with a interface argument.\n";
3984 9d83d01f Renato Botelho
	$dhcp6cscript .= "dmips=\${new_domain_name_servers}\n";
3985
	$dhcp6cscript .= "dmnames=\${new_domain_name}\n";
3986
	$dhcp6cscript .= "/usr/local/sbin/fcgicli -f /etc/rc.newwanipv6 -d \"interface={$wanif}&dmnames=\${dmnames}&dmips=\${dmips}\"\n";
3987 d53a9a51 smos
	/* Add wide-dhcp6c shell script here. Because we can not pass a argument to it. */
3988 b0059636 Ermal
	if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", $dhcp6cscript)) {
3989 d53a9a51 smos
		printf("Error: cannot open dhcp6c_{$interface}_script.sh in interface_dhcpv6_configure() for writing.\n");
3990 d12ae241 Renato Botelho
		unset($dhcp6cscript);
3991 d53a9a51 smos
		return 1;
3992
	}
3993 d12ae241 Renato Botelho
	unset($dhcp6cscript);
3994 b0059636 Ermal
	@chmod("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", 0755);
3995 d53a9a51 smos
3996 29f2f07a Ermal
	$rtsoldscript = "#!/bin/sh\n";
3997
	$rtsoldscript .= "# This shell script launches dhcp6c and configured gateways for this interface.\n";
3998
	$rtsoldscript .= "echo $2 > {$g['tmp_path']}/{$wanif}_routerv6\n";
3999
	$rtsoldscript .= "echo $2 > {$g['tmp_path']}/{$wanif}_defaultgwv6\n";
4000 32916e5c Phil Davis
	$rtsoldscript .= "/usr/bin/logger -t rtsold \"Received RA specifying route \$2 for interface {$interface}({$wanif})\"\n";
4001 e0bc2a6c marjohn56
4002 f50f74a4 Phil Davis
	/* non ipoe Process */
4003 e0bc2a6c marjohn56
	if (!isset($wancfg['dhcp6withoutra'])) {
4004 f50f74a4 Phil Davis
		$rtsoldscript .= "if [ -f {$g['varrun_path']}/dhcp6c_{$wanif}.pid ]; then\n";
4005
		$rtsoldscript .= "\t/bin/pkill -F {$g['varrun_path']}/dhcp6c_{$wanif}.pid\n";
4006
		$rtsoldscript .= "\t/bin/sleep 1\n";
4007
		$rtsoldscript .= "fi\n";
4008
	} else {
4009
		$rtsoldscript .= "\t/bin/sleep 1\n";
4010
	}
4011
	$debugOption = isset($wancfg['dhcp6debug']) ? "-D" : "-d";
4012 e0bc2a6c marjohn56
4013
	/* add the start of dhcp6c to the rtsold script if we are going to wait for ra */
4014 f50f74a4 Phil Davis
	if (!isset($wancfg['dhcp6withoutra'])) {
4015
		$rtsoldscript .= "/usr/local/sbin/dhcp6c {$debugOption} -c {$g['varetc_path']}/dhcp6c_{$interface}.conf -p {$g['varrun_path']}/dhcp6c_{$wanif}.pid {$wanif}\n";
4016
		$rtsoldscript .= "/usr/bin/logger -t rtsold \"Starting dhcp6 client for interface {$interface}({$wanif})\"\n";
4017
	}
4018 29f2f07a Ermal
	/* Add wide-dhcp6c shell script here. Because we can not pass a argument to it. */
4019
	if (!@file_put_contents("{$g['varetc_path']}/rtsold_{$wanif}_script.sh", $rtsoldscript)) {
4020 0876ed6c Chris Buechler
		printf("Error: cannot open rtsold_{$wanif}_script.sh in interface_dhcpv6_configure() for writing.\n");
4021 29f2f07a Ermal
		unset($rtsoldscript);
4022
		return 1;
4023
	}
4024
	unset($rtsoldscript);
4025
	@chmod("{$g['varetc_path']}/rtsold_{$wanif}_script.sh", 0755);
4026 d53a9a51 smos
4027 c65d3051 Seth Mos
	/* accept router advertisements for this interface */
4028 49047fb4 smos
	log_error("Accept router advertisements on interface {$wanif} ");
4029 100c7be0 Seth Mos
	mwexec("/sbin/ifconfig {$wanif} inet6 accept_rtadv");
4030 61c4383d smos
4031 29f2f07a Ermal
	/* fire up rtsold for IPv6 RAs first, this backgrounds immediately. It will call dhcp6c */
4032 7fed35c8 Ermal
	if (isvalidpid("{$g['varrun_path']}/rtsold_{$wanif}.pid")) {
4033 29f2f07a Ermal
		killbypid("{$g['varrun_path']}/rtsold_{$wanif}.pid");
4034 7fed35c8 Ermal
		sleep(2);
4035
	}
4036 e0bc2a6c marjohn56
4037
	/* start dhcp6c here if we don't want to wait for ra */
4038 f50f74a4 Phil Davis
	if (isset($wancfg['dhcp6withoutra'])) {
4039
		kill_dhcp6client_process($wanif);
4040
4041 efd07e5e Phil Davis
		mwexec("/usr/local/sbin/dhcp6c {$debugOption} -c {$g['varetc_path']}/dhcp6c_wan.conf -p {$g['varrun_path']}/dhcp6c_{$wanif}.pid {$wanif}");
4042 e0bc2a6c marjohn56
		mwexec("/usr/bin/logger -t info 'Starting dhcp6 client for interface wan({$wanif} in DHCP6 without RA mode)'");
4043 f50f74a4 Phil Davis
	}
4044 9b6010ff Ermal
	mwexec("/usr/sbin/rtsold -1 -p {$g['varrun_path']}/rtsold_{$wanif}.pid -O {$g['varetc_path']}/rtsold_{$wanif}_script.sh {$wanif}");
4045 82769dfe smos
4046 a8f5790a Renato Botelho
	/* NOTE: will be called from rtsold invoked script
4047 29f2f07a Ermal
	 * link_interface_to_track6($interface, "update");
4048
	 */
4049 b0059636 Ermal
4050 ed395640 Seth Mos
	return 0;
4051
}
4052
4053 f4dd8b4c N0YB
function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif) {
4054
	global $g;
4055
4056
	$send_options = "";
4057
	if ($wancfg['adv_dhcp6_interface_statement_send_options'] != '') {
4058 489091dc Daniel Wilhelm
		$options = DHCP_Config_Option_Split($wancfg['adv_dhcp6_interface_statement_send_options']);
4059 f4dd8b4c N0YB
		foreach ($options as $option) {
4060
			$send_options .= "\tsend " . trim($option) . ";\n";
4061
		}
4062
	}
4063
4064
	$request_options = "";
4065
	if ($wancfg['adv_dhcp6_interface_statement_request_options'] != '') {
4066 489091dc Daniel Wilhelm
		$options = DHCP_Config_Option_Split($wancfg['adv_dhcp6_interface_statement_request_options']);
4067 f4dd8b4c N0YB
		foreach ($options as $option) {
4068
			$request_options .= "\trequest " . trim($option) . ";\n";
4069
		}
4070
	}
4071
4072
	$information_only = "";
4073 cf73302f Phil Davis
	if ($wancfg['adv_dhcp6_interface_statement_information_only_enable'] != '') {
4074 f4dd8b4c N0YB
		$information_only = "\tinformation-only;\n";
4075 cf73302f Phil Davis
	}
4076 f4dd8b4c N0YB
4077
	$script = "\tscript \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\";\n";
4078 cf73302f Phil Davis
	if ($wancfg['adv_dhcp6_interface_statement_script'] != '') {
4079 f4dd8b4c N0YB
		$script = "\tscript \"{$wancfg['adv_dhcp6_interface_statement_script']}\";\n";
4080 cf73302f Phil Davis
	}
4081 f4dd8b4c N0YB
4082
	$interface_statement  = "interface";
4083
	$interface_statement .= " {$wanif}";
4084
	$interface_statement .= " {\n";
4085
	$interface_statement .= "$send_options";
4086
	$interface_statement .= "$request_options";
4087
	$interface_statement .= "$information_only";
4088
	$interface_statement .= "$script";
4089
	$interface_statement .= "};\n";
4090
4091
	$id_assoc_statement_address = "";
4092
	if ($wancfg['adv_dhcp6_id_assoc_statement_address_enable'] != '') {
4093
		$id_assoc_statement_address .= "id-assoc";
4094
		$id_assoc_statement_address .= " na";
4095 cf73302f Phil Davis
		if (is_numeric($wancfg['adv_dhcp6_id_assoc_statement_address_id'])) {
4096 f4dd8b4c N0YB
			$id_assoc_statement_address .= " {$wancfg['adv_dhcp6_id_assoc_statement_address_id']}";
4097 cf73302f Phil Davis
		}
4098 f4dd8b4c N0YB
		$id_assoc_statement_address .= " { ";
4099
4100 cf73302f Phil Davis
		if (($wancfg['adv_dhcp6_id_assoc_statement_address'] != '') &&
4101
		    (is_numeric($wancfg['adv_dhcp6_id_assoc_statement_address_pltime']) ||
4102
		    ($wancfg['adv_dhcp6_id_assoc_statement_address_pltime'] == 'infinity'))) {
4103 f4dd8b4c N0YB
			$id_assoc_statement_address .= "\n\taddress";
4104
			$id_assoc_statement_address .= " {$wancfg['adv_dhcp6_id_assoc_statement_address']}";
4105
			$id_assoc_statement_address .= " {$wancfg['adv_dhcp6_id_assoc_statement_address_pltime']}";
4106 cf73302f Phil Davis
			if ((is_numeric($wancfg['adv_dhcp6_id_assoc_statement_address_vltime'])) ||
4107
			    ($wancfg['adv_dhcp6_id_assoc_statement_address_vltime'] == 'infinity')) {
4108 f4dd8b4c N0YB
				$id_assoc_statement_address .= " {$wancfg['adv_dhcp6_id_assoc_statement_address_vltime']}";
4109 cf73302f Phil Davis
			}
4110 f4dd8b4c N0YB
			$id_assoc_statement_address .= ";\n";
4111
		}
4112
4113 6c07db48 Phil Davis
		$id_assoc_statement_address .= "};\n";
4114 f4dd8b4c N0YB
	}
4115
4116
	$id_assoc_statement_prefix = "";
4117
	if ($wancfg['adv_dhcp6_id_assoc_statement_prefix_enable'] != '') {
4118
		$id_assoc_statement_prefix .= "id-assoc";
4119
		$id_assoc_statement_prefix .= " pd";
4120 cf73302f Phil Davis
		if (is_numeric($wancfg['adv_dhcp6_id_assoc_statement_prefix_id'])) {
4121 f4dd8b4c N0YB
			$id_assoc_statement_prefix .= " {$wancfg['adv_dhcp6_id_assoc_statement_prefix_id']}";
4122 cf73302f Phil Davis
		}
4123 f4dd8b4c N0YB
		$id_assoc_statement_prefix .= " { ";
4124
4125 cf73302f Phil Davis
		if (($wancfg['adv_dhcp6_id_assoc_statement_prefix'] != '') &&
4126
		    (is_numeric($wancfg['adv_dhcp6_id_assoc_statement_prefix_pltime']) ||
4127 086cf944 Phil Davis
		    ($wancfg['adv_dhcp6_id_assoc_statement_prefix_pltime'] == 'infinity'))) {
4128 f4dd8b4c N0YB
			$id_assoc_statement_prefix .= "\n\tprefix";
4129
			$id_assoc_statement_prefix .= " {$wancfg['adv_dhcp6_id_assoc_statement_prefix']}";
4130
			$id_assoc_statement_prefix .= " {$wancfg['adv_dhcp6_id_assoc_statement_prefix_pltime']}";
4131 cf73302f Phil Davis
			if ((is_numeric($wancfg['adv_dhcp6_id_assoc_statement_prefix_vltime'])) ||
4132
			    ($wancfg['adv_dhcp6_id_assoc_statement_prefix_vltime'] == 'infinity')) {
4133 f4dd8b4c N0YB
				$id_assoc_statement_prefix .= " {$wancfg['adv_dhcp6_id_assoc_statement_prefix_vltime']}";
4134 cf73302f Phil Davis
			}
4135 f4dd8b4c N0YB
			$id_assoc_statement_prefix .= ";";
4136
		}
4137
4138
		if (is_numeric($wancfg['adv_dhcp6_prefix_interface_statement_sla_id'])) {
4139
			$id_assoc_statement_prefix .= "\n\tprefix-interface";
4140
			$id_assoc_statement_prefix .= " {$wanif}";
4141
			$id_assoc_statement_prefix .= " {\n";
4142
			$id_assoc_statement_prefix .= "\t\tsla-id {$wancfg['adv_dhcp6_prefix_interface_statement_sla_id']};\n";
4143 cf73302f Phil Davis
			if (($wancfg['adv_dhcp6_prefix_interface_statement_sla_len'] >= 0) &&
4144
			    ($wancfg['adv_dhcp6_prefix_interface_statement_sla_len'] <= 128)) {
4145 6990ad35 Phil Davis
				$id_assoc_statement_prefix .= "\t\tsla-len {$wancfg['adv_dhcp6_prefix_interface_statement_sla_len']};\n";
4146 cf73302f Phil Davis
			}
4147 f4dd8b4c N0YB
			$id_assoc_statement_prefix .= "\t};";
4148
		}
4149
4150 cf73302f Phil Davis
		if (($wancfg['adv_dhcp6_id_assoc_statement_prefix'] != '') ||
4151 086cf944 Phil Davis
		    (is_numeric($wancfg['adv_dhcp6_prefix_interface_statement_sla_id']))) {
4152 f4dd8b4c N0YB
			$id_assoc_statement_prefix .= "\n";
4153
		}
4154
4155 6c07db48 Phil Davis
		$id_assoc_statement_prefix .= "};\n";
4156 f4dd8b4c N0YB
	}
4157
4158
	$authentication_statement = "";
4159 cf73302f Phil Davis
	if (($wancfg['adv_dhcp6_authentication_statement_authname'] != '') &&
4160
	    ($wancfg['adv_dhcp6_authentication_statement_protocol'] == 'delayed')) {
4161 f4dd8b4c N0YB
		$authentication_statement .= "authentication";
4162
		$authentication_statement .= " {$wancfg['adv_dhcp6_authentication_statement_authname']}";
4163
		$authentication_statement .= " {\n";
4164
		$authentication_statement .= "\tprotocol {$wancfg['adv_dhcp6_authentication_statement_protocol']};\n";
4165 cf73302f Phil Davis
		if (preg_match("/(hmac(-)?md5)||(HMAC(-)?MD5)/", $wancfg['adv_dhcp6_authentication_statement_algorithm'])) {
4166 f4dd8b4c N0YB
			$authentication_statement .= "\talgorithm {$wancfg['adv_dhcp6_authentication_statement_algorithm']};\n";
4167 cf73302f Phil Davis
		}
4168
		if ($wancfg['adv_dhcp6_authentication_statement_rdm'] == 'monocounter') {
4169 f4dd8b4c N0YB
			$authentication_statement .= "\trdm {$wancfg['adv_dhcp6_authentication_statement_rdm']};\n";
4170 cf73302f Phil Davis
		}
4171 f4dd8b4c N0YB
		$authentication_statement .= "};\n";
4172
	}
4173
4174
	$key_info_statement = "";
4175 cf73302f Phil Davis
	if (($wancfg['adv_dhcp6_key_info_statement_keyname'] != '') &&
4176
	    ($wancfg['adv_dhcp6_key_info_statement_realm'] != '') &&
4177
	    (is_numeric($wancfg['adv_dhcp6_key_info_statement_keyid'])) &&
4178
	    ($wancfg['adv_dhcp6_key_info_statement_secret'] != '')) {
4179 f4dd8b4c N0YB
		$key_info_statement .= "keyinfo";
4180
		$key_info_statement .= " {$wancfg['adv_dhcp6_key_info_statement_keyname']}";
4181
		$key_info_statement .= " {\n";
4182
		$key_info_statement .= "\trealm \"{$wancfg['adv_dhcp6_key_info_statement_realm']}\";\n";
4183
		$key_info_statement .= "\tkeyid {$wancfg['adv_dhcp6_key_info_statement_keyid']};\n";
4184
		$key_info_statement .= "\tsecret \"{$wancfg['adv_dhcp6_key_info_statement_secret']}\";\n";
4185 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'])) {
4186 f4dd8b4c N0YB
			$key_info_statement .= "\texpire \"{$wancfg['adv_dhcp6_key_info_statement_expire']}\";\n";
4187 cf73302f Phil Davis
		}
4188 f4dd8b4c N0YB
		$key_info_statement .= "};\n";
4189
	}
4190
4191
	$dhcp6cconf  = $interface_statement;
4192
	$dhcp6cconf .= $id_assoc_statement_address;
4193
	$dhcp6cconf .= $id_assoc_statement_prefix;
4194
	$dhcp6cconf .= $authentication_statement;
4195
	$dhcp6cconf .= $key_info_statement;
4196
4197
	$dhcp6cconf = DHCP6_Config_File_Substitutions($wancfg, $wanif, $dhcp6cconf);
4198
4199
	return $dhcp6cconf;
4200
}
4201
4202
4203
function DHCP6_Config_File_Override($wancfg, $wanif) {
4204
4205 f31052c7 k-paulius
	$dhcp6cconf = @file_get_contents($wancfg['adv_dhcp6_config_file_override_path']);
4206 f4dd8b4c N0YB
4207 f31052c7 k-paulius
	if ($dhcp6cconf === false) {
4208 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']));
4209 f31052c7 k-paulius
		return '';
4210
	} else {
4211 fc1f2003 k-paulius
		return DHCP6_Config_File_Substitutions($wancfg, $wanif, $dhcp6cconf);;
4212 f31052c7 k-paulius
	}
4213 f4dd8b4c N0YB
}
4214
4215
4216
function DHCP6_Config_File_Substitutions($wancfg, $wanif, $dhcp6cconf) {
4217
4218
	$dhcp6cconf = DHCP_Config_File_Substitutions($wancfg, $wanif, $dhcp6cconf);
4219
4220
	return $dhcp6cconf;
4221
}
4222
4223
4224 8103bd1e Seth Mos
function interface_dhcp_configure($interface = "wan") {
4225 ed395640 Seth Mos
	global $config, $g;
4226
4227
	$wancfg = $config['interfaces'][$interface];
4228
	$wanif = $wancfg['if'];
4229 cf73302f Phil Davis
	if (empty($wancfg)) {
4230 df9e93f0 Ermal
		$wancfg = array();
4231 cf73302f Phil Davis
	}
4232 5b237745 Scott Ullrich
4233 0311dbd5 Scott Ullrich
	/* generate dhclient_wan.conf */
4234 67ee1ec5 Ermal Luçi
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
4235 5b237745 Scott Ullrich
	if (!$fd) {
4236 ebc9c152 Phil Davis
		log_error(sprintf(gettext("Error: cannot open dhclient_%s.conf in interface_dhcp_configure() for writing."), $interface));
4237 5b237745 Scott Ullrich
		return 1;
4238
	}
4239 eb772abd Scott Ullrich
4240 2305d4c5 Scott Ullrich
	if ($wancfg['dhcphostname']) {
4241
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
4242
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
4243
	} else {
4244
		$dhclientconf_hostname = "";
4245
	}
4246
4247 85a5da13 Ermal Luçi
	$wanif = get_real_interface($interface);
4248 df9e93f0 Ermal
	if (empty($wanif)) {
4249 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("Invalid interface \"%s\" in interface_dhcp_configure()"), $interface));
4250 c1cc447c gnhb
		return 0;
4251 3a906378 gnhb
	}
4252 1c3ddd9e Renato Botelho
	$dhclientconf = "";
4253 be45aa79 Renato Botelho
4254 6d76590c Scott Ullrich
	$dhclientconf .= <<<EOD
4255 67ee1ec5 Ermal Luçi
interface "{$wanif}" {
4256 76d3b9a3 Chris Buechler
timeout 60;
4257 88810240 smos
retry 15;
4258 ce69a638 Scott Ullrich
select-timeout 0;
4259
initial-interval 1;
4260 2305d4c5 Scott Ullrich
	{$dhclientconf_hostname}
4261
	script "/sbin/dhclient-script";
4262 57c83fd6 jim-p
EOD;
4263
4264 cf73302f Phil Davis
	if (is_ipaddrv4($wancfg['dhcprejectfrom'])) {
4265
		$dhclientconf .= <<<EOD
4266 57c83fd6 jim-p
4267
	reject {$wancfg['dhcprejectfrom']};
4268
EOD;
4269 cf73302f Phil Davis
	}
4270 57c83fd6 jim-p
	$dhclientconf .= <<<EOD
4271
4272 5b237745 Scott Ullrich
}
4273
4274
EOD;
4275
4276 f4dd8b4c N0YB
	// DHCP Config File Advanced
4277 cf73302f Phil Davis
	if ($wancfg['adv_dhcp_config_advanced']) {
4278
		$dhclientconf = DHCP_Config_File_Advanced($interface, $wancfg, $wanif);
4279
	}
4280 f4dd8b4c N0YB
4281 cf73302f Phil Davis
	if (is_ipaddr($wancfg['alias-address'])) {
4282
		$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
4283
		$dhclientconf .= <<<EOD
4284 bc40d758 Seth Mos
alias {
4285 6c07db48 Phil Davis
	interface "{$wanif}";
4286 bc40d758 Seth Mos
	fixed-address {$wancfg['alias-address']};
4287
	option subnet-mask {$subnetmask};
4288
}
4289
4290
EOD;
4291 cf73302f Phil Davis
	}
4292 f4dd8b4c N0YB
4293
	// DHCP Config File Override
4294 cf73302f Phil Davis
	if ($wancfg['adv_dhcp_config_file_override']) {
4295
		$dhclientconf = DHCP_Config_File_Override($wancfg, $wanif);
4296
	}
4297 f4dd8b4c N0YB
4298 5b237745 Scott Ullrich
	fwrite($fd, $dhclientconf);
4299
	fclose($fd);
4300 eb772abd Scott Ullrich
4301 d7147b1c Scott Ullrich
	/* bring wan interface up before starting dhclient */
4302 cf73302f Phil Davis
	if ($wanif) {
4303 3a906378 gnhb
		interfaces_bring_up($wanif);
4304 cf73302f Phil Davis
	} else {
4305 d18f3f6e Phil Davis
		log_error(sprintf(gettext("Could not bring up %s interface in interface_dhcp_configure()"), $wanif));
4306 cf73302f Phil Davis
	}
4307 eacc8c14 Scott Ullrich
4308 60ef0911 Renato Botelho
	/* Make sure dhclient is not running */
4309
	kill_dhclient_process($wanif);
4310
4311 7149c4e7 Seth Mos
	/* fire up dhclient */
4312 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");
4313 0119d2f7 Scott Ullrich
4314 5b237745 Scott Ullrich
	return 0;
4315
}
4316
4317 f4dd8b4c N0YB
function DHCP_Config_File_Advanced($interface, $wancfg, $wanif) {
4318
4319
	$hostname = "";
4320
	if ($wancfg['dhcphostname'] != '') {
4321 672d7e7b N0YB
		$hostname = "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
4322 f4dd8b4c N0YB
	}
4323
4324
	/* DHCP Protocol Timings */
4325
	$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");
4326
	foreach ($protocol_timings as $Protocol_Timing => $PT_Name) {
4327
		$pt_variable = "{$Protocol_Timing}";
4328
		${$pt_variable} = "";
4329
		if ($wancfg[$Protocol_Timing] != "") {
4330
			${$pt_variable} = "{$PT_Name} {$wancfg[$Protocol_Timing]};\n";
4331
		}
4332
	}
4333
4334
	$send_options = "";
4335
	if ($wancfg['adv_dhcp_send_options'] != '') {
4336 489091dc Daniel Wilhelm
		$options = DHCP_Config_Option_Split($wancfg['adv_dhcp_send_options']);
4337 f4dd8b4c N0YB
		foreach ($options as $option) {
4338
			$send_options .= "\tsend " . trim($option) . ";\n";
4339
		}
4340
	}
4341
4342
	$request_options = "";
4343
	if ($wancfg['adv_dhcp_request_options'] != '') {
4344
		$request_options = "\trequest {$wancfg['adv_dhcp_request_options']};\n";
4345
	}
4346
4347
	$required_options = "";
4348
	if ($wancfg['adv_dhcp_required_options'] != '') {
4349 f669800c N0YB
		$required_options = "\trequire {$wancfg['adv_dhcp_required_options']};\n";
4350 f4dd8b4c N0YB
	}
4351
4352
	$option_modifiers = "";
4353
	if ($wancfg['adv_dhcp_option_modifiers'] != '') {
4354 489091dc Daniel Wilhelm
		$modifiers = DHCP_Config_Option_Split($wancfg['adv_dhcp_option_modifiers']);
4355 f4dd8b4c N0YB
		foreach ($modifiers as $modifier) {
4356
			$option_modifiers .= "\t" . trim($modifier) . ";\n";
4357
		}
4358
	}
4359
4360 cf73302f Phil Davis
	$dhclientconf  = "interface \"{$wanif}\" {\n";
4361
	$dhclientconf .= "\n";
4362
	$dhclientconf .= "# DHCP Protocol Timing Values\n";
4363
	$dhclientconf .= "{$adv_dhcp_pt_timeout}";
4364
	$dhclientconf .= "{$adv_dhcp_pt_retry}";
4365
	$dhclientconf .= "{$adv_dhcp_pt_select_timeout}";
4366
	$dhclientconf .= "{$adv_dhcp_pt_reboot}";
4367
	$dhclientconf .= "{$adv_dhcp_pt_backoff_cutoff}";
4368
	$dhclientconf .= "{$adv_dhcp_pt_initial_interval}";
4369
	$dhclientconf .= "\n";
4370
	$dhclientconf .= "# DHCP Protocol Options\n";
4371
	$dhclientconf .= "{$hostname}";
4372
	$dhclientconf .= "{$send_options}";
4373
	$dhclientconf .= "{$request_options}";
4374
	$dhclientconf .= "{$required_options}";
4375
	$dhclientconf .= "{$option_modifiers}";
4376
	$dhclientconf .= "\n";
4377 8f1a91f7 Nash Kaminski
	if (is_ipaddrv4($wancfg['dhcprejectfrom'])) {
4378 eb6cbf8c Nash Kaminski
		$dhclientconf .= "reject {$wancfg['dhcprejectfrom']};\n";
4379
	}
4380 cf73302f Phil Davis
	$dhclientconf .= "\tscript \"/sbin/dhclient-script\";\n";
4381
	$dhclientconf .= "}\n";
4382 f4dd8b4c N0YB
4383
	$dhclientconf = DHCP_Config_File_Substitutions($wancfg, $wanif, $dhclientconf);
4384
4385
	return $dhclientconf;
4386
}
4387
4388 489091dc Daniel Wilhelm
function DHCP_Config_Option_Split($option_string) {
4389 c34b069e Daniel Wilhelm
	preg_match_all('/[^",]*(?:"[^"]*"[^",]*)+(?:"[^",]*)?|[^,]+/m', $option_string, $matches, PREG_PATTERN_ORDER);
4390
	return $matches ? $matches[0] : [];
4391 489091dc Daniel Wilhelm
}
4392 f4dd8b4c N0YB
4393
function DHCP_Config_File_Override($wancfg, $wanif) {
4394
4395 9329ec08 k-paulius
	$dhclientconf = @file_get_contents($wancfg['adv_dhcp_config_file_override_path']);
4396 f4dd8b4c N0YB
4397 9329ec08 k-paulius
	if ($dhclientconf === false) {
4398 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']));
4399 9329ec08 k-paulius
		return '';
4400
	} else {
4401
		return DHCP_Config_File_Substitutions($wancfg, $wanif, $dhclientconf);
4402
	}
4403 f4dd8b4c N0YB
}
4404
4405
4406
function DHCP_Config_File_Substitutions($wancfg, $wanif, $dhclientconf) {
4407
4408
	/* Apply Interface Substitutions */
4409
	$dhclientconf = str_replace("{interface}", "{$wanif}", $dhclientconf);
4410
4411
	/* Apply Hostname Substitutions */
4412
	$dhclientconf = str_replace("{hostname}", $wancfg['dhcphostname'], $dhclientconf);
4413
4414
	/* Arrays of MAC Address Types, Cases, Delimiters */
4415
	/* ASCII or HEX, Upper or Lower Case, Various Delimiters (none, space, colon, hyphen, period) */
4416
	$various_mac_types      = array("mac_addr_ascii", "mac_addr_hex");
4417
	$various_mac_cases      = array("U", "L");
4418
	$various_mac_delimiters = array("", " ", ":", "-", ".");
4419
4420
	/* Apply MAC Address Substitutions */
4421
	foreach ($various_mac_types as $various_mac_type) {
4422
		foreach ($various_mac_cases as $various_mac_case) {
4423
			foreach ($various_mac_delimiters as $various_mac_delimiter) {
4424
4425
				$res = stripos($dhclientconf, $various_mac_type . $various_mac_case . $various_mac_delimiter);
4426
				if ($res !== false) {
4427
4428 f416763b Phil Davis
					/* Get MAC Address as ASCII String With Colon (:) delimiters */
4429 cf73302f Phil Davis
					if ("$various_mac_case" == "U") {
4430
						$dhcpclientconf_mac = strtoupper(get_interface_mac($wanif));
4431
					}
4432
					if ("$various_mac_case" == "L") {
4433
						$dhcpclientconf_mac = strtolower(get_interface_mac($wanif));
4434
					}
4435 f4dd8b4c N0YB
4436
					if ("$various_mac_type" == "mac_addr_hex") {
4437
						/* Convert MAC ascii string to HEX with colon (:) delimiters. */
4438
						$dhcpclientconf_mac = str_replace(":", "", $dhcpclientconf_mac);
4439
						$dhcpclientconf_mac_hex = "";
4440
						$delimiter = "";
4441 cf73302f Phil Davis
						for ($i = 0; $i < strlen($dhcpclientconf_mac); $i++) {
4442 f4dd8b4c N0YB
							$dhcpclientconf_mac_hex .= $delimiter. bin2hex($dhcpclientconf_mac[$i]);
4443
							$delimiter = ":";
4444
						}
4445
						$dhcpclientconf_mac = $dhcpclientconf_mac_hex;
4446
					}
4447
4448
					/* MAC Address Delimiter Substitutions */
4449
					$dhcpclientconf_mac = str_replace(":", $various_mac_delimiter, $dhcpclientconf_mac);
4450
4451
					/* Apply MAC Address Substitutions */
4452
					$dhclientconf = str_replace("{" . $various_mac_type . $various_mac_case . $various_mac_delimiter . "}", $dhcpclientconf_mac, $dhclientconf);
4453
				}
4454
			}
4455
		}
4456
	}
4457
4458
	return $dhclientconf;
4459
}
4460
4461 42753d25 Ermal Lu?i
function interfaces_group_setup() {
4462
	global $config;
4463
4464 cf73302f Phil Davis
	if (!is_array($config['ifgroups']['ifgroupentry'])) {
4465 42753d25 Ermal Lu?i
		return;
4466 cf73302f Phil Davis
	}
4467 42753d25 Ermal Lu?i
4468 cf73302f Phil Davis
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar) {
4469 42753d25 Ermal Lu?i
		interface_group_setup($groupar);
4470 cf73302f Phil Davis
	}
4471 42753d25 Ermal Lu?i
4472
	return;
4473
}
4474
4475 abcb2bed Ermal Lu?i
function interface_group_setup(&$groupname /* The parameter is an array */) {
4476 42753d25 Ermal Lu?i
	global $config;
4477
4478 cf73302f Phil Davis
	if (!is_array($groupname)) {
4479 42753d25 Ermal Lu?i
		return;
4480 cf73302f Phil Davis
	}
4481 42753d25 Ermal Lu?i
	$members = explode(" ", $groupname['members']);
4482 cf73302f Phil Davis
	foreach ($members as $ifs) {
4483 42753d25 Ermal Lu?i
		$realif = get_real_interface($ifs);
4484 cf73302f Phil Davis
		if ($realif && does_interface_exist($realif)) {
4485 42753d25 Ermal Lu?i
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
4486 cf73302f Phil Davis
		}
4487 42753d25 Ermal Lu?i
	}
4488
4489
	return;
4490
}
4491 48f23632 Ermal
4492 06182467 Renato Botelho
function is_interface_group($if) {
4493
	global $config;
4494
4495 cf73302f Phil Davis
	if (is_array($config['ifgroups']['ifgroupentry'])) {
4496 06182467 Renato Botelho
		foreach ($config['ifgroups']['ifgroupentry'] as $groupentry) {
4497 cf73302f Phil Davis
			if ($groupentry['ifname'] === $if) {
4498 06182467 Renato Botelho
				return true;
4499 cf73302f Phil Davis
			}
4500 06182467 Renato Botelho
		}
4501 cf73302f Phil Davis
	}
4502 06182467 Renato Botelho
4503
	return false;
4504
}
4505
4506 48f23632 Ermal
function interface_group_add_member($interface, $groupname) {
4507 ed62880b Ermal
	$interface = get_real_interface($interface);
4508 cf73302f Phil Davis
	if (does_interface_exist($interface)) {
4509 67de15fc Renato Botelho
		mwexec("/sbin/ifconfig {$interface} group " . escapeshellarg($groupname), true);
4510 cf73302f Phil Davis
	}
4511 48f23632 Ermal
}
4512 be45aa79 Renato Botelho
4513 e8910ad4 Ermal Lu?i
/* COMPAT Function */
4514 afb2de1b Ermal Lu?i
function convert_friendly_interface_to_real_interface_name($interface) {
4515
	return get_real_interface($interface);
4516
}
4517
4518 e8910ad4 Ermal Lu?i
/* COMPAT Function */
4519 eba938e3 Scott Ullrich
function get_real_wan_interface($interface = "wan") {
4520 abb31ea4 Ermal Luçi
	return get_real_interface($interface);
4521
}
4522 afb2de1b Ermal Lu?i
4523 e8910ad4 Ermal Lu?i
/* COMPAT Function */
4524 eba938e3 Scott Ullrich
function get_current_wan_address($interface = "wan") {
4525 abb31ea4 Ermal Luçi
	return get_interface_ip($interface);
4526
}
4527
4528 afb2de1b Ermal Lu?i
/*
4529
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
4530
 */
4531 5e0a3256 Ermal LUÇI
function convert_real_interface_to_friendly_interface_name($interface = "wan", $checkparent = false) {
4532 7061ba0f Renato Botelho
	global $config;
4533 afb2de1b Ermal Lu?i
4534 7061ba0f Renato Botelho
	/* XXX: For speed reasons reference directly the interface array */
4535 74e1e658 jim-p
	$ifdescrs = &$config['interfaces'];
4536 7061ba0f Renato Botelho
	//$ifdescrs = get_configured_interface_list(false, true);
4537 afb2de1b Ermal Lu?i
4538 7061ba0f Renato Botelho
	foreach ($ifdescrs as $if => $ifname) {
4539 cf73302f Phil Davis
		if ($if == $interface || $ifname['if'] == $interface) {
4540 7061ba0f Renato Botelho
			return $if;
4541 cf73302f Phil Davis
		}
4542 afb2de1b Ermal Lu?i
4543 cf73302f Phil Davis
		if (get_real_interface($if) == $interface) {
4544 7061ba0f Renato Botelho
			return $if;
4545 cf73302f Phil Davis
		}
4546 af637766 Erik Fonnesbeck
4547 cf73302f Phil Davis
		if ($checkparent == false) {
4548 5e0a3256 Ermal LUÇI
			continue;
4549 cf73302f Phil Davis
		}
4550 5e0a3256 Ermal LUÇI
4551 d6101e23 Ermal
		$int = get_parent_interface($if, true);
4552
		if (is_array($int)) {
4553
			foreach ($int as $iface) {
4554 cf73302f Phil Davis
				if ($iface == $interface) {
4555 d6101e23 Ermal
					return $if;
4556 cf73302f Phil Davis
				}
4557 d6101e23 Ermal
			}
4558
		}
4559 7061ba0f Renato Botelho
	}
4560 1d66a364 Ermal
4561 cf73302f Phil Davis
	if ($interface == "enc0") {
4562 5ebb2954 Ermal
		return 'IPsec';
4563 cf73302f Phil Davis
	}
4564 afb2de1b Ermal Lu?i
}
4565
4566
/* attempt to resolve interface to friendly descr */
4567
function convert_friendly_interface_to_friendly_descr($interface) {
4568 1c3ddd9e Renato Botelho
	global $config;
4569 afb2de1b Ermal Lu?i
4570 1c3ddd9e Renato Botelho
	switch ($interface) {
4571 cf73302f Phil Davis
		case "l2tp":
4572
			$ifdesc = "L2TP";
4573
			break;
4574
		case "pptp":
4575
			$ifdesc = "PPTP";
4576 57c52d45 Erik Fonnesbeck
			break;
4577 cf73302f Phil Davis
		case "pppoe":
4578
			$ifdesc = "PPPoE";
4579
			break;
4580
		case "openvpn":
4581
			$ifdesc = "OpenVPN";
4582
			break;
4583 67c3b4dc Chris Buechler
		case "lo0":
4584
			$ifdesc = "Loopback";
4585
			break;
4586 cf73302f Phil Davis
		case "enc0":
4587
		case "ipsec":
4588
		case "IPsec":
4589
			$ifdesc = "IPsec";
4590
			break;
4591
		default:
4592
			if (isset($config['interfaces'][$interface])) {
4593
				if (empty($config['interfaces'][$interface]['descr'])) {
4594
					$ifdesc = strtoupper($interface);
4595
				} else {
4596
					$ifdesc = strtoupper($config['interfaces'][$interface]['descr']);
4597
				}
4598
				break;
4599
			} else if (substr($interface, 0, 4) == '_vip') {
4600
				if (is_array($config['virtualip']['vip'])) {
4601
					foreach ($config['virtualip']['vip'] as $counter => $vip) {
4602 6c07db48 Phil Davis
						if ($vip['mode'] == "carp") {
4603 a5bed5a2 Luiz Otavio O Souza
							if ($interface == "_vip{$vip['uniqid']}") {
4604 cf73302f Phil Davis
								return "{$vip['subnet']} - {$vip['descr']}";
4605
							}
4606
						}
4607
					}
4608
				}
4609
			} else if (substr($interface, 0, 5) == '_lloc') {
4610
				return get_interface_linklocal($interface);
4611
			} else {
4612
				/* if list */
4613
				$ifdescrs = get_configured_interface_with_descr(false, true);
4614
				foreach ($ifdescrs as $if => $ifname) {
4615
					if ($if == $interface || $ifname == $interface) {
4616
						return $ifname;
4617 f2dd61a7 Ermal
					}
4618
				}
4619
			}
4620 cf73302f Phil Davis
			break;
4621 1c3ddd9e Renato Botelho
	}
4622 afb2de1b Ermal Lu?i
4623 1c3ddd9e Renato Botelho
	return $ifdesc;
4624 afb2de1b Ermal Lu?i
}
4625
4626
function convert_real_interface_to_friendly_descr($interface) {
4627
4628 1c3ddd9e Renato Botelho
	$ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
4629 afb2de1b Ermal Lu?i
4630 cf73302f Phil Davis
	if (!empty($ifdesc)) {
4631 a1b5f07b Ermal
		return convert_friendly_interface_to_friendly_descr($ifdesc);
4632 cf73302f Phil Davis
	}
4633 afb2de1b Ermal Lu?i
4634 1c3ddd9e Renato Botelho
	return $interface;
4635 afb2de1b Ermal Lu?i
}
4636
4637 532b0fb8 Ermal Lu?i
/*
4638 d5dfcb52 gnhb
 *  get_parent_interface($interface):
4639 20cb9803 gnhb
 *			--returns the (real or virtual) parent interface(s) array for a given interface friendly name (i.e. wan)
4640
 *				or virtual interface (i.e. vlan)
4641
 *				(We need array because MLPPP and bridge interfaces have more than one parent.)
4642
 *			-- returns $interface passed in if $interface parent is not found
4643
 *			-- returns empty array if an invalid interface is passed
4644
 *	(Only handles ppps and vlans now.)
4645 532b0fb8 Ermal Lu?i
 */
4646 d6101e23 Ermal
function get_parent_interface($interface, $avoidrecurse = false) {
4647 d5dfcb52 gnhb
	global $config;
4648 532b0fb8 Ermal Lu?i
4649 20cb9803 gnhb
	$parents = array();
4650
	//Check that we got a valid interface passed
4651
	$realif = get_real_interface($interface);
4652 cf73302f Phil Davis
	if ($realif == NULL) {
4653 20cb9803 gnhb
		return $parents;
4654 cf73302f Phil Davis
	}
4655 20cb9803 gnhb
4656
	// If we got a real interface, find it's friendly assigned name
4657 cf73302f Phil Davis
	if ($interface == $realif && $avoidrecurse == false) {
4658 ebcbc110 Ermal
		$interface = convert_real_interface_to_friendly_interface_name($interface);
4659 cf73302f Phil Davis
	}
4660 be45aa79 Renato Botelho
4661 20cb9803 gnhb
	if (!empty($interface) && isset($config['interfaces'][$interface])) {
4662
		$ifcfg = $config['interfaces'][$interface];
4663
		switch ($ifcfg['ipaddr']) {
4664
			case "ppp":
4665
			case "pppoe":
4666
			case "pptp":
4667
			case "l2tp":
4668 cf73302f Phil Davis
				if (empty($parents)) {
4669
					if (is_array($config['ppps']['ppp'])) {
4670 20cb9803 gnhb
						foreach ($config['ppps']['ppp'] as $pppidx => $ppp) {
4671 02b8bfae Renato Botelho
							if ($ifcfg['if'] == $ppp['if']) {
4672 20cb9803 gnhb
								$ports = explode(',', $ppp['ports']);
4673 cf73302f Phil Davis
								foreach ($ports as $pid => $parent_if) {
4674 20cb9803 gnhb
									$parents[$pid] = get_real_interface($parent_if);
4675 cf73302f Phil Davis
								}
4676 20cb9803 gnhb
								break;
4677
							}
4678
						}
4679 cf73302f Phil Davis
					}
4680
				}
4681 20cb9803 gnhb
				break;
4682
			case "dhcp":
4683
			case "static":
4684
			default:
4685
				// Handle _vlans
4686 bc73d959 Ermal LUÇI
				if (strpos($realif, '_vlan') !== FALSE) {
4687
					if (is_array($config['vlans']['vlan'])) {
4688
						foreach ($config['vlans']['vlan'] as $vlanidx => $vlan) {
4689
							if ($ifcfg['if'] == $vlan['vlanif']) {
4690 20cb9803 gnhb
								$parents[0] = $vlan['if'];
4691
								break;
4692
							}
4693 bc73d959 Ermal LUÇI
						}
4694
					}
4695
				}
4696 20cb9803 gnhb
				break;
4697 3e5d0d1d Ermal
		}
4698
	}
4699 be45aa79 Renato Botelho
4700 dec8e5ff David Wood
	if (empty($parents)) {
4701
		// Handle _vlans not assigned to an interface
4702
		if (strpos($realif, '_vlan') !== FALSE) {
4703
			if (is_array($config['vlans']['vlan'])) {
4704
				foreach ($config['vlans']['vlan'] as $vlanidx => $vlan) {
4705
					if ($realif == $vlan['vlanif']) {
4706
						$parents[0] = $vlan['if'];
4707
						break;
4708
					}
4709
				}
4710
			}
4711
		}
4712
	}
4713
4714 cf73302f Phil Davis
	if (empty($parents)) {
4715 20cb9803 gnhb
		$parents[0] = $realif;
4716 cf73302f Phil Davis
	}
4717 be45aa79 Renato Botelho
4718 20cb9803 gnhb
	return $parents;
4719 532b0fb8 Ermal Lu?i
}
4720
4721 8332312b Chris Buechler
/*
4722
 *  get_parent_physical_interface($interface):
4723
 *   - returns an array of parent interface(s) for a given interface friendly name (e.g. wan)
4724
 *  differs from get_parent_interface in that it traverses to find the physical NICs on lagg
4725
 */
4726
function get_parent_physical_interface($interface) {
4727
	global $config;
4728
4729
	$realif = get_parent_interface($interface);
4730
4731
	if (substr($realif[0], 0, 4) == "lagg") {
4732
		foreach ($config['laggs']['lagg'] as $lagg) {
4733
			if ($realif[0] == $lagg['laggif']) {
4734
				return explode(",", $lagg['members']);
4735
			}
4736
		}
4737
	} else {
4738
		return $realif;
4739
	}
4740
}
4741
4742 263e2b7e Erik Fonnesbeck
function interface_is_wireless_clone($wlif) {
4743 cf73302f Phil Davis
	if (!stristr($wlif, "_wlan")) {
4744 263e2b7e Erik Fonnesbeck
		return false;
4745
	} else {
4746
		return true;
4747
	}
4748
}
4749
4750 1d072761 Erik Fonnesbeck
function interface_get_wireless_base($wlif) {
4751 cf73302f Phil Davis
	if (!stristr($wlif, "_wlan")) {
4752 34808d4e Erik Fonnesbeck
		return $wlif;
4753
	} else {
4754
		return substr($wlif, 0, stripos($wlif, "_wlan"));
4755
	}
4756
}
4757
4758 1d072761 Erik Fonnesbeck
function interface_get_wireless_clone($wlif) {
4759 cf73302f Phil Davis
	if (!stristr($wlif, "_wlan")) {
4760 34808d4e Erik Fonnesbeck
		return $wlif . "_wlan0";
4761
	} else {
4762
		return $wlif;
4763
	}
4764
}
4765
4766 33e71f10 jim-p
function get_real_interface($interface = "wan", $family = "all", $realv6iface = false, $flush = true) {
4767 ee3576dd Ermal
	global $config, $g;
4768 cfc707f7 Scott Ullrich
4769 521cfa2f Ermal Lu?i
	$wanif = NULL;
4770 c515ea57 Scott Ullrich
4771 67ee1ec5 Ermal Luçi
	switch ($interface) {
4772 cf73302f Phil Davis
		case "l2tp":
4773
			$wanif = "l2tp";
4774 89f171b0 Ermal LUÇI
			break;
4775 cf73302f Phil Davis
		case "pptp":
4776
			$wanif = "pptp";
4777 6d5446a2 Ermal
			break;
4778 cf73302f Phil Davis
		case "pppoe":
4779
			$wanif = "pppoe";
4780 6d5446a2 Ermal
			break;
4781 cf73302f Phil Davis
		case "openvpn":
4782
			$wanif = "openvpn";
4783
			break;
4784 94d494fb Luiz Otavio O Souza
		case "IPsec":
4785 cf73302f Phil Davis
		case "ipsec":
4786
		case "enc0":
4787
			$wanif = "enc0";
4788
			break;
4789
		case "ppp":
4790
			$wanif = "ppp";
4791
			break;
4792
		default:
4793
			if (substr($interface, 0, 4) == '_vip') {
4794 2a5960b0 Luiz Otavio O Souza
				$wanif = get_configured_vip_interface($interface);
4795 d9901ff4 Chris Buechler
				if (!empty($wanif)) {
4796 2a5960b0 Luiz Otavio O Souza
					$wanif = get_real_interface($wanif);
4797 d9901ff4 Chris Buechler
				}
4798 cf73302f Phil Davis
				break;
4799
			} else if (substr($interface, 0, 5) == '_lloc') {
4800
				$interface = substr($interface, 5);
4801 c6555b1d Luiz Otavio O Souza
			} else if (strstr($interface, "_vlan") ||
4802
			    does_interface_exist($interface, $flush)) {
4803 cf73302f Phil Davis
				/*
4804
				 * If a real interface was already passed simply
4805
				 * pass the real interface back.  This encourages
4806
				 * the usage of this function in more cases so that
4807
				 * we can combine logic for more flexibility.
4808
				 */
4809
				$wanif = $interface;
4810
				break;
4811
			}
4812 568b1358 Scott Ullrich
4813 cf73302f Phil Davis
			if (empty($config['interfaces'][$interface])) {
4814 b6c1f22f Ermal
				break;
4815 cf73302f Phil Davis
			}
4816
4817
			$cfg = &$config['interfaces'][$interface];
4818
4819
			if ($family == "inet6") {
4820
				switch ($cfg['ipaddrv6']) {
4821
					case "6rd":
4822
					case "6to4":
4823
						$wanif = "{$interface}_stf";
4824
						break;
4825
					case 'pppoe':
4826
					case 'ppp':
4827
					case 'l2tp':
4828
					case 'pptp':
4829 086cf944 Phil Davis
						if (is_array($cfg['wireless']) || preg_match($g['wireless_regex'], $cfg['if'])) {
4830 cf73302f Phil Davis
							$wanif = interface_get_wireless_clone($cfg['if']);
4831
						} else {
4832
							$wanif = $cfg['if'];
4833
						}
4834
						break;
4835
					default:
4836
						switch ($cfg['ipaddr']) {
4837
							case 'pppoe':
4838
							case 'ppp':
4839
							case 'l2tp':
4840
							case 'pptp':
4841
								if (isset($cfg['dhcp6usev4iface']) && $realv6iface === false) {
4842
									$wanif = $cfg['if'];
4843
								} else {
4844
									$parents = get_parent_interface($interface);
4845
									if (!empty($parents[0])) {
4846
										$wanif = $parents[0];
4847
									} else {
4848
										$wanif = $cfg['if'];
4849
									}
4850
								}
4851
								break;
4852
							default:
4853
								if (is_array($cfg['wireless']) || preg_match($g['wireless_regex'], $cfg['if'])) {
4854
									$wanif = interface_get_wireless_clone($cfg['if']);
4855
								} else {
4856
									$wanif = $cfg['if'];
4857
								}
4858
								break;
4859
						}
4860
						break;
4861
				}
4862
			} else {
4863
				// Wireless cloned NIC support (FreeBSD 8+)
4864
				// interface name format: $parentnic_wlanparentnic#
4865
				// example: ath0_wlan0
4866 086cf944 Phil Davis
				if (is_array($cfg['wireless']) || preg_match($g['wireless_regex'], $cfg['if'])) {
4867 4cc3bb6c Ermal
					$wanif = interface_get_wireless_clone($cfg['if']);
4868 cf73302f Phil Davis
				} else {
4869 4cc3bb6c Ermal
					$wanif = $cfg['if'];
4870 15a73ba8 Ermal
				}
4871 b6c1f22f Ermal
			}
4872 cf73302f Phil Davis
			break;
4873 c515ea57 Scott Ullrich
	}
4874
4875 1c3ddd9e Renato Botelho
	return $wanif;
4876 5b237745 Scott Ullrich
}
4877
4878 9ff8c299 Seth Mos
/* Guess the physical interface by providing a IP address */
4879 afb2de1b Ermal Lu?i
function guess_interface_from_ip($ipaddress) {
4880 aa5acb42 Ermal
4881
	$family = '';
4882 cf73302f Phil Davis
	if (is_ipaddrv4($ipaddress)) {
4883 aa5acb42 Ermal
		$family = 'inet';
4884 cf73302f Phil Davis
	}
4885
	if (empty($family) && is_ipaddrv6($ipaddress)) {
4886 aa5acb42 Ermal
		$family = 'inet6';
4887 cf73302f Phil Davis
	}
4888 aa5acb42 Ermal
4889 cf73302f Phil Davis
	if (empty($family)) {
4890 1c3ddd9e Renato Botelho
		return false;
4891 cf73302f Phil Davis
	}
4892 aa5acb42 Ermal
4893
	/* create a route table we can search */
4894
	$output = '';
4895
	$_gb = exec("/sbin/route -n get -{$family} " . escapeshellarg($ipaddress) . " | /usr/bin/awk '/interface/ { print \$2; };'", $output);
4896
	$output[0] = trim($output[0], " \n");
4897 cf73302f Phil Davis
	if (!empty($output[0])) {
4898 aa5acb42 Ermal
		return $output[0];
4899 cf73302f Phil Davis
	}
4900 aa5acb42 Ermal
4901
	return false;
4902 afb2de1b Ermal Lu?i
}
4903
4904
/*
4905
 * find_ip_interface($ip): return the interface where an ip is defined
4906 59231855 Darren Embry
 *   (or if $bits is specified, where an IP within the subnet is defined)
4907 afb2de1b Ermal Lu?i
 */
4908 2027b4c7 bcyrill
function find_ip_interface($ip, $bits = null) {
4909 cf73302f Phil Davis
	if (!is_ipaddr($ip)) {
4910 2027b4c7 bcyrill
		return false;
4911 cf73302f Phil Davis
	}
4912 a8f5790a Renato Botelho
4913 2027b4c7 bcyrill
	$isv6ip = is_ipaddrv6($ip);
4914 a8f5790a Renato Botelho
4915 59231855 Darren Embry
	/* if list */
4916
	$ifdescrs = get_configured_interface_list();
4917 be45aa79 Renato Botelho
4918 59231855 Darren Embry
	foreach ($ifdescrs as $ifdescr => $ifname) {
4919 2027b4c7 bcyrill
		$ifip = ($isv6ip) ? get_interface_ipv6($ifname) : get_interface_ip($ifname);
4920 cf73302f Phil Davis
		if (is_null($ifip)) {
4921 2027b4c7 bcyrill
			continue;
4922 cf73302f Phil Davis
		}
4923 ec8b4d8d Ermal
		if (is_null($bits)) {
4924 2027b4c7 bcyrill
			if ($ip == $ifip) {
4925 59231855 Darren Embry
				$int = get_real_interface($ifname);
4926
				return $int;
4927
			}
4928 cf73302f Phil Davis
		} else {
4929 2027b4c7 bcyrill
			if (ip_in_subnet($ifip, $ip . "/" . $bits)) {
4930 59231855 Darren Embry
				$int = get_real_interface($ifname);
4931
				return $int;
4932
			}
4933
		}
4934
	}
4935 ec8b4d8d Ermal
4936 59231855 Darren Embry
	return false;
4937
}
4938 afb2de1b Ermal Lu?i
4939 59231855 Darren Embry
/*
4940
 * find_virtual_ip_alias($ip): return the virtual IP alias where an IP is found
4941
 *   (or if $bits is specified, where an IP within the subnet is found)
4942
 */
4943
function find_virtual_ip_alias($ip, $bits = null) {
4944
	global $config;
4945 a8f5790a Renato Botelho
4946 59231855 Darren Embry
	if (!is_array($config['virtualip']['vip'])) {
4947
		return false;
4948
	}
4949 cf73302f Phil Davis
	if (!is_ipaddr($ip)) {
4950 6b207f73 bcyrill
		return false;
4951 cf73302f Phil Davis
	}
4952 a8f5790a Renato Botelho
4953 6b207f73 bcyrill
	$isv6ip = is_ipaddrv6($ip);
4954 a8f5790a Renato Botelho
4955 59231855 Darren Embry
	foreach ($config['virtualip']['vip'] as $vip) {
4956
		if ($vip['mode'] === "ipalias") {
4957 cf73302f Phil Davis
			if (is_ipaddrv6($vip['subnet']) != $isv6ip) {
4958 6b207f73 bcyrill
				continue;
4959 cf73302f Phil Davis
			}
4960 ec8b4d8d Ermal
			if (is_null($bits)) {
4961 59231855 Darren Embry
				if (ip_in_subnet($ip, $vip['subnet'] . "/" . $vip['subnet_bits'])) {
4962
					return $vip;
4963
				}
4964 cf73302f Phil Davis
			} else {
4965
				if (($isv6ip && check_subnetsv6_overlap($ip, $bits, $vip['subnet'], $vip['subnet_bits'])) ||
4966
				    (!$isv6ip && check_subnets_overlap($ip, $bits, $vip['subnet'], $vip['subnet_bits']))) {
4967 59231855 Darren Embry
					return $vip;
4968
				}
4969
			}
4970 abcb2bed Ermal Lu?i
		}
4971 59231855 Darren Embry
	}
4972
	return false;
4973 afb2de1b Ermal Lu?i
}
4974
4975 7a04cd20 Ermal
function link_interface_to_track6($int, $action = "") {
4976
	global $config;
4977
4978 cf73302f Phil Davis
	if (empty($int)) {
4979 7a04cd20 Ermal
		return;
4980 cf73302f Phil Davis
	}
4981 7a04cd20 Ermal
4982
	if (is_array($config['interfaces'])) {
4983
		$list = array();
4984
		foreach ($config['interfaces'] as $ifname => $ifcfg) {
4985 cf73302f Phil Davis
			if (!isset($ifcfg['enable'])) {
4986 7a04cd20 Ermal
				continue;
4987 cf73302f Phil Davis
			}
4988 7a04cd20 Ermal
			if (!empty($ifcfg['ipaddrv6']) && $ifcfg['track6-interface'] == $int) {
4989 cf73302f Phil Davis
				if ($action == "update") {
4990 7a04cd20 Ermal
					interface_track6_configure($ifname, $ifcfg);
4991 cf73302f Phil Davis
				} else if ($action == "") {
4992 7a04cd20 Ermal
					$list[$ifname] = $ifcfg;
4993 cf73302f Phil Davis
				}
4994 7a04cd20 Ermal
			}
4995
		}
4996
		return $list;
4997
	}
4998
}
4999
5000 2b58f94e Ermal LUÇI
function interface_find_child_cfgmtu($realiface) {
5001
	global $config;
5002
5003
	$interface = convert_real_interface_to_friendly_interface_name($realiface);
5004
	$vlans = link_interface_to_vlans($realiface);
5005 9cf9f30f Phil Davis
	$qinqs = link_interface_to_qinqs($realiface);
5006 2b58f94e Ermal LUÇI
	$bridge = link_interface_to_bridge($realiface);
5007
	if (!empty($interface)) {
5008
		$gifs = link_interface_to_gif($interface);
5009
		$gres = link_interface_to_gre($interface);
5010
	} else {
5011
		$gifs = array();
5012
		$gres = array();
5013
	}
5014
5015
	$mtu = 0;
5016 2f8f9d5a Ermal LUÇI
	if (is_array($vlans)) {
5017
		foreach ($vlans as $vlan) {
5018
			$ifass = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
5019 cf73302f Phil Davis
			if (empty($ifass)) {
5020 2f8f9d5a Ermal LUÇI
				continue;
5021 cf73302f Phil Davis
			}
5022 2f8f9d5a Ermal LUÇI
			if (!empty($config['interfaces'][$ifass]['mtu'])) {
5023 cf73302f Phil Davis
				if (intval($config['interfaces'][$ifass]['mtu']) > $mtu) {
5024 2f8f9d5a Ermal LUÇI
					$mtu = intval($config['interfaces'][$ifass]['mtu']);
5025 cf73302f Phil Davis
				}
5026 2f8f9d5a Ermal LUÇI
			}
5027 2b58f94e Ermal LUÇI
		}
5028
	}
5029 9cf9f30f Phil Davis
	if (is_array($qinqs)) {
5030
		foreach ($qinqs as $qinq) {
5031
			$ifass = convert_real_interface_to_friendly_interface_name($qinq['vlanif']);
5032
			if (empty($ifass)) {
5033
				continue;
5034
			}
5035
			if (!empty($config['interfaces'][$ifass]['mtu'])) {
5036
				if (intval($config['interfaces'][$ifass]['mtu']) > $mtu) {
5037
					$mtu = intval($config['interfaces'][$ifass]['mtu']);
5038
				}
5039
			}
5040
		}
5041
	}
5042 2f8f9d5a Ermal LUÇI
	if (is_array($gifs)) {
5043 5be76d38 Renato Botelho
		foreach ($gifs as $gif) {
5044
			$ifass = convert_real_interface_to_friendly_interface_name($gif['gifif']);
5045 cf73302f Phil Davis
			if (empty($ifass)) {
5046 2f8f9d5a Ermal LUÇI
				continue;
5047 cf73302f Phil Davis
			}
5048 2f8f9d5a Ermal LUÇI
			if (!empty($config['interfaces'][$ifass]['mtu'])) {
5049 cf73302f Phil Davis
				if (intval($config['interfaces'][$ifass]['mtu']) > $mtu) {
5050 2f8f9d5a Ermal LUÇI
					$mtu = intval($config['interfaces'][$ifass]['mtu']);
5051 cf73302f Phil Davis
				}
5052 2f8f9d5a Ermal LUÇI
			}
5053 2b58f94e Ermal LUÇI
		}
5054
	}
5055 2f8f9d5a Ermal LUÇI
	if (is_array($gres)) {
5056 5be76d38 Renato Botelho
		foreach ($gres as $gre) {
5057
			$ifass = convert_real_interface_to_friendly_interface_name($gre['greif']);
5058 cf73302f Phil Davis
			if (empty($ifass)) {
5059 2f8f9d5a Ermal LUÇI
				continue;
5060 cf73302f Phil Davis
			}
5061 2f8f9d5a Ermal LUÇI
			if (!empty($config['interfaces'][$ifass]['mtu'])) {
5062 cf73302f Phil Davis
				if (intval($config['interfaces'][$ifass]['mtu']) > $mtu) {
5063 2f8f9d5a Ermal LUÇI
					$mtu = intval($config['interfaces'][$ifass]['mtu']);
5064 cf73302f Phil Davis
				}
5065 2f8f9d5a Ermal LUÇI
			}
5066 2b58f94e Ermal LUÇI
		}
5067
	}
5068
	$ifass = convert_real_interface_to_friendly_interface_name($bridge);
5069
	if (!empty($ifass) && !empty($config['interfaces'][$ifass]['mtu'])) {
5070 cf73302f Phil Davis
		if (intval($config['interfaces'][$ifass]['mtu']) > $mtu) {
5071 2b58f94e Ermal LUÇI
			$mtu = intval($config['interfaces'][$ifass]['mtu']);
5072 cf73302f Phil Davis
		}
5073 2b58f94e Ermal LUÇI
	}
5074
	unset($vlans, $bridge, $gifs, $gres, $ifass, $vlan);
5075
5076
	return $mtu;
5077
}
5078
5079 7850de1c Ermal Lu?i
function link_interface_to_vlans($int, $action = "") {
5080
	global $config;
5081
5082 cf73302f Phil Davis
	if (empty($int)) {
5083 7850de1c Ermal Lu?i
		return;
5084 cf73302f Phil Davis
	}
5085 7850de1c Ermal Lu?i
5086
	if (is_array($config['vlans']['vlan'])) {
5087 a362a23a Ermal
		$ifaces = array();
5088 1c3ddd9e Renato Botelho
		foreach ($config['vlans']['vlan'] as $vlan) {
5089 fa4a331f Ermal
			if ($int == $vlan['if']) {
5090 7850de1c Ermal Lu?i
				if ($action == "update") {
5091 fa4a331f Ermal
					interfaces_bring_up($int);
5092 cf73302f Phil Davis
				} else {
5093 a362a23a Ermal
					$ifaces[$vlan['tag']] = $vlan;
5094 cf73302f Phil Davis
				}
5095 7850de1c Ermal Lu?i
			}
5096
		}
5097 cf73302f Phil Davis
		if (!empty($ifaces)) {
5098 a362a23a Ermal
			return $ifaces;
5099 cf73302f Phil Davis
		}
5100 7850de1c Ermal Lu?i
	}
5101
}
5102
5103 9cf9f30f Phil Davis
function link_interface_to_qinqs($int, $action = "") {
5104
	global $config;
5105
5106
	if (empty($int)) {
5107
		return;
5108
	}
5109
5110
	if (is_array($config['qinqs']['qinqentry'])) {
5111
		$ifaces = array();
5112
		foreach ($config['qinqs']['qinqentry'] as $qinq) {
5113
			if ($int == $qinq['if']) {
5114
				if ($action == "update") {
5115
					interfaces_bring_up($int);
5116
				} else {
5117
					$ifaces[$qinq['tag']] = $qinq;
5118
				}
5119
			}
5120
		}
5121
		if (!empty($ifaces)) {
5122
			return $ifaces;
5123
		}
5124
	}
5125
}
5126
5127 89f171b0 Ermal LUÇI
function link_interface_to_vips($int, $action = "", $vhid = '') {
5128 1c3ddd9e Renato Botelho
	global $config;
5129 e5ac67ed Ermal Lu?i
5130 6fd9645e Chris Buechler
	$updatevips = false;
5131 1c3ddd9e Renato Botelho
	if (is_array($config['virtualip']['vip'])) {
5132 75201355 Ermal
		$result = array();
5133 dcadda55 Ermal
		foreach ($config['virtualip']['vip'] as $vip) {
5134 55a72d31 Chris Buechler
			if (substr($vip['interface'], 0, 4) == "_vip") {
5135 3185f659 Luiz Otavio O Souza
				$iface = get_configured_vip_interface($vip['interface']);
5136 55a72d31 Chris Buechler
			} else {
5137 3185f659 Luiz Otavio O Souza
				$iface = $vip['interface'];
5138 55a72d31 Chris Buechler
			}
5139
			if ($int != $iface) {
5140 3185f659 Luiz Otavio O Souza
				continue;
5141 55a72d31 Chris Buechler
			}
5142 3185f659 Luiz Otavio O Souza
			if ($action == "update") {
5143 6fd9645e Chris Buechler
				$updatevips = true;
5144 3185f659 Luiz Otavio O Souza
			} else {
5145 89a7d8d0 Luiz Otavio O Souza
				if (empty($vhid) || ($vhid == $vip['vhid']) ||
5146
				    substr($vip['interface'], 0, 4) == "_vip") {
5147 3185f659 Luiz Otavio O Souza
					$result[] = $vip;
5148 89f171b0 Ermal LUÇI
				}
5149 7850de1c Ermal Lu?i
			}
5150 dcadda55 Ermal
		}
5151 6fd9645e Chris Buechler
		if ($updatevips === true) {
5152
			interfaces_vips_configure($int);
5153
		}
5154 75201355 Ermal
		return $result;
5155 dcadda55 Ermal
	}
5156 3185f659 Luiz Otavio O Souza
5157
	return NULL;
5158 e5ac67ed Ermal Lu?i
}
5159
5160 afb2de1b Ermal Lu?i
/****f* interfaces/link_interface_to_bridge
5161
 * NAME
5162
 *   link_interface_to_bridge - Finds out a bridge group for an interface
5163
 * INPUTS
5164
 *   $ip
5165
 * RESULT
5166
 *   bridge[0-99]
5167
 ******/
5168
function link_interface_to_bridge($int) {
5169 1c3ddd9e Renato Botelho
	global $config;
5170 afb2de1b Ermal Lu?i
5171 1c3ddd9e Renato Botelho
	if (is_array($config['bridges']['bridged'])) {
5172
		foreach ($config['bridges']['bridged'] as $bridge) {
5173 cf73302f Phil Davis
			if (in_array($int, explode(',', $bridge['members']))) {
5174 1c3ddd9e Renato Botelho
				return "{$bridge['bridgeif']}";
5175 cf73302f Phil Davis
			}
5176 a639bb91 Ermal
		}
5177
	}
5178 afb2de1b Ermal Lu?i
}
5179
5180 48f23632 Ermal
function link_interface_to_group($int) {
5181 1c3ddd9e Renato Botelho
	global $config;
5182 48f23632 Ermal
5183 ed62880b Ermal
	$result = array();
5184
5185 1c3ddd9e Renato Botelho
	if (is_array($config['ifgroups']['ifgroupentry'])) {
5186
		foreach ($config['ifgroups']['ifgroupentry'] as $group) {
5187 cf73302f Phil Davis
			if (in_array($int, explode(" ", $group['members']))) {
5188 ed62880b Ermal
				$result[$group['ifname']] = $int;
5189 cf73302f Phil Davis
			}
5190 48f23632 Ermal
		}
5191
	}
5192 ed62880b Ermal
5193
	return $result;
5194 48f23632 Ermal
}
5195
5196 afb2de1b Ermal Lu?i
function link_interface_to_gre($interface) {
5197 1c3ddd9e Renato Botelho
	global $config;
5198 afb2de1b Ermal Lu?i
5199 ed62880b Ermal
	$result = array();
5200
5201 1c3ddd9e Renato Botelho
	if (is_array($config['gres']['gre'])) {
5202 cf73302f Phil Davis
		foreach ($config['gres']['gre'] as $gre) {
5203
			if ($gre['if'] == $interface) {
5204 ed62880b Ermal
				$result[] = $gre;
5205 cf73302f Phil Davis
			}
5206
		}
5207 ed62880b Ermal
	}
5208
5209
	return $result;
5210 afb2de1b Ermal Lu?i
}
5211
5212
function link_interface_to_gif($interface) {
5213 1c3ddd9e Renato Botelho
	global $config;
5214 afb2de1b Ermal Lu?i
5215 ed62880b Ermal
	$result = array();
5216
5217 1c3ddd9e Renato Botelho
	if (is_array($config['gifs']['gif'])) {
5218 cf73302f Phil Davis
		foreach ($config['gifs']['gif'] as $gif) {
5219
			if ($gif['if'] == $interface) {
5220 1c3ddd9e Renato Botelho
				$result[] = $gif;
5221 cf73302f Phil Davis
			}
5222
		}
5223 ed62880b Ermal
	}
5224
5225
	return $result;
5226 afb2de1b Ermal Lu?i
}
5227
5228
/*
5229
 * find_interface_ip($interface): return the interface ip (first found)
5230
 */
5231 a8f5790a Renato Botelho
function find_interface_ip($interface, $flush = false) {
5232 afb2de1b Ermal Lu?i
	global $interface_ip_arr_cache;
5233 01f1b601 Ermal
	global $interface_sn_arr_cache;
5234 afb2de1b Ermal Lu?i
5235
	$interface = str_replace("\n", "", $interface);
5236 be45aa79 Renato Botelho
5237 cf73302f Phil Davis
	if (!does_interface_exist($interface)) {
5238 afb2de1b Ermal Lu?i
		return;
5239 cf73302f Phil Davis
	}
5240 afb2de1b Ermal Lu?i
5241
	/* Setup IP cache */
5242
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
5243 3f70e618 Ermal Lu?i
		$ifinfo = pfSense_get_interface_addresses($interface);
5244
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
5245 01f1b601 Ermal
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
5246 afb2de1b Ermal Lu?i
	}
5247
5248
	return $interface_ip_arr_cache[$interface];
5249
}
5250
5251 47593ac6 Seth Mos
/*
5252
 * find_interface_ipv6($interface): return the interface ip (first found)
5253
 */
5254 a8f5790a Renato Botelho
function find_interface_ipv6($interface, $flush = false) {
5255 47593ac6 Seth Mos
	global $interface_ipv6_arr_cache;
5256
	global $interface_snv6_arr_cache;
5257 31ace4ea Seth Mos
	global $config;
5258 be45aa79 Renato Botelho
5259 31bdb9e5 smos
	$interface = trim($interface);
5260
	$interface = get_real_interface($interface);
5261 be45aa79 Renato Botelho
5262 cf73302f Phil Davis
	if (!does_interface_exist($interface)) {
5263 47593ac6 Seth Mos
		return;
5264 cf73302f Phil Davis
	}
5265 47593ac6 Seth Mos
5266
	/* Setup IP cache */
5267
	if (!isset($interface_ipv6_arr_cache[$interface]) or $flush) {
5268 ce14e37b Ermal
		$ifinfo = pfSense_get_interface_addresses($interface);
5269
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddr6'];
5270
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbits6'];
5271 47593ac6 Seth Mos
	}
5272
5273
	return $interface_ipv6_arr_cache[$interface];
5274
}
5275
5276 81a3b6f5 smos
/*
5277
 * find_interface_ipv6_ll($interface): return the interface ipv6 link local (first found)
5278
 */
5279 a8f5790a Renato Botelho
function find_interface_ipv6_ll($interface, $flush = false) {
5280 58418355 smos
	global $interface_llv6_arr_cache;
5281 81a3b6f5 smos
	global $config;
5282 be45aa79 Renato Botelho
5283 81a3b6f5 smos
	$interface = str_replace("\n", "", $interface);
5284 be45aa79 Renato Botelho
5285 cf73302f Phil Davis
	if (!does_interface_exist($interface)) {
5286 81a3b6f5 smos
		return;
5287 cf73302f Phil Davis
	}
5288 81a3b6f5 smos
5289
	/* Setup IP cache */
5290 58418355 smos
	if (!isset($interface_llv6_arr_cache[$interface]) or $flush) {
5291 ce14e37b Ermal
		$ifinfo = pfSense_getall_interface_addresses($interface);
5292 cf73302f Phil Davis
		foreach ($ifinfo as $line) {
5293 ce14e37b Ermal
			if (strstr($line, ":")) {
5294
				$parts = explode("/", $line);
5295 cf73302f Phil Davis
				if (is_linklocal($parts[0])) {
5296 ce14e37b Ermal
					$ifinfo['linklocal'] = $parts[0];
5297 81a3b6f5 smos
				}
5298
			}
5299
		}
5300 58418355 smos
		$interface_llv6_arr_cache[$interface] = $ifinfo['linklocal'];
5301 81a3b6f5 smos
	}
5302 58418355 smos
	return $interface_llv6_arr_cache[$interface];
5303 81a3b6f5 smos
}
5304
5305 a8f5790a Renato Botelho
function find_interface_subnet($interface, $flush = false) {
5306 afb2de1b Ermal Lu?i
	global $interface_sn_arr_cache;
5307 01f1b601 Ermal
	global $interface_ip_arr_cache;
5308 afb2de1b Ermal Lu?i
5309
	$interface = str_replace("\n", "", $interface);
5310 cf73302f Phil Davis
	if (does_interface_exist($interface) == false) {
5311 afb2de1b Ermal Lu?i
		return;
5312 cf73302f Phil Davis
	}
5313 afb2de1b Ermal Lu?i
5314
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
5315 bd96e1fe Ermal Lu?i
		$ifinfo = pfSense_get_interface_addresses($interface);
5316 01f1b601 Ermal
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
5317 bd96e1fe Ermal Lu?i
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
5318 1c3ddd9e Renato Botelho
	}
5319 afb2de1b Ermal Lu?i
5320
	return $interface_sn_arr_cache[$interface];
5321
}
5322
5323 a8f5790a Renato Botelho
function find_interface_subnetv6($interface, $flush = false) {
5324 47593ac6 Seth Mos
	global $interface_snv6_arr_cache;
5325
	global $interface_ipv6_arr_cache;
5326
5327
	$interface = str_replace("\n", "", $interface);
5328 cf73302f Phil Davis
	if (does_interface_exist($interface) == false) {
5329 47593ac6 Seth Mos
		return;
5330 cf73302f Phil Davis
	}
5331 47593ac6 Seth Mos
5332
	if (!isset($interface_snv6_arr_cache[$interface]) or $flush) {
5333 2c3924a1 Ermal
		$ifinfo = pfSense_get_interface_addresses($interface);
5334
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddr6'];
5335
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbits6'];
5336 1c3ddd9e Renato Botelho
	}
5337 47593ac6 Seth Mos
5338
	return $interface_snv6_arr_cache[$interface];
5339
}
5340
5341 e19b7d1e Ermal
function ip_in_interface_alias_subnet($interface, $ipalias) {
5342
	global $config;
5343
5344 cf73302f Phil Davis
	if (empty($interface) || !is_ipaddr($ipalias)) {
5345 e8471084 Ermal
		return false;
5346 cf73302f Phil Davis
	}
5347 e19b7d1e Ermal
	if (is_array($config['virtualip']['vip'])) {
5348 1c3ddd9e Renato Botelho
		foreach ($config['virtualip']['vip'] as $vip) {
5349
			switch ($vip['mode']) {
5350 cf73302f Phil Davis
				case "ipalias":
5351
					if ($vip['interface'] <> $interface) {
5352
						break;
5353
					}
5354
					$subnet = is_ipaddrv6($ipalias) ? gen_subnetv6($vip['subnet'], $vip['subnet_bits']) : gen_subnet($vip['subnet'], $vip['subnet_bits']);
5355
					if (ip_in_subnet($ipalias, $subnet . "/" . $vip['subnet_bits'])) {
5356
						return true;
5357
					}
5358 1c3ddd9e Renato Botelho
					break;
5359
			}
5360
		}
5361 e19b7d1e Ermal
	}
5362 e8471084 Ermal
5363
	return false;
5364 e19b7d1e Ermal
}
5365
5366 89f171b0 Ermal LUÇI
function get_possible_listen_ips($include_ipv6_link_local=false) {
5367
5368
	$interfaces = get_configured_interface_with_descr();
5369
	foreach ($interfaces as $iface => $ifacename) {
5370
		if ($include_ipv6_link_local) {
5371
			/* This is to avoid going though added ll below */
5372 cf73302f Phil Davis
			if (substr($iface, 0, 5) == '_lloc') {
5373 89f171b0 Ermal LUÇI
				continue;
5374 cf73302f Phil Davis
			}
5375 89f171b0 Ermal LUÇI
			$llip = find_interface_ipv6_ll(get_real_interface($iface));
5376
			if (!empty($llip)) {
5377
				$interfaces["_lloc{$iface}"] = "{$ifacename} IPv6 Link-Local";
5378
			}
5379
		}
5380
	}
5381 2a5960b0 Luiz Otavio O Souza
	$viplist = get_configured_vip_list();
5382
	foreach ($viplist as $vip => $address) {
5383
		$interfaces[$vip] = $address;
5384 d9901ff4 Chris Buechler
		if (get_vip_descr($address)) {
5385 2a5960b0 Luiz Otavio O Souza
			$interfaces[$vip] .= " (". get_vip_descr($address) .")";
5386 d9901ff4 Chris Buechler
		}
5387 cf73302f Phil Davis
	}
5388 89f171b0 Ermal LUÇI
5389
	$interfaces['lo0'] = 'Localhost';
5390
5391
	return $interfaces;
5392
}
5393 cf73302f Phil Davis
5394 89f171b0 Ermal LUÇI
function get_possible_traffic_source_addresses($include_ipv6_link_local=false) {
5395
	global $config;
5396
5397
	$sourceips = get_possible_listen_ips($include_ipv6_link_local);
5398
	foreach (array('server', 'client') as $mode) {
5399
		if (is_array($config['openvpn']["openvpn-{$mode}"])) {
5400
			foreach ($config['openvpn']["openvpn-{$mode}"] as $id => $setting) {
5401
				if (!isset($setting['disable'])) {
5402 a08d5055 Phil Davis
					$sourceips_key = 'ovpn' . substr($mode, 0, 1) . $setting['vpnid'];
5403 d18f3f6e Phil Davis
					$sourceips[$sourceips_key] = gettext("OpenVPN") . " " . $mode . ": " . htmlspecialchars($setting['description']);
5404 89f171b0 Ermal LUÇI
				}
5405
			}
5406
		}
5407
	}
5408
	return $sourceips;
5409
}
5410
5411 a8f5790a Renato Botelho
function get_interface_ip($interface = "wan") {
5412 cf73302f Phil Davis
5413 3564bcb5 Chris Buechler
	if (substr($interface, 0, 4) == '_vip') {
5414 2a5960b0 Luiz Otavio O Souza
		return get_configured_vip_ipv4($interface);
5415 1e505631 Chris Buechler
	} else if (substr($interface, 0, 5) == '_lloc') {
5416
		/* No link-local address for v4. */
5417
		return null;
5418 3564bcb5 Chris Buechler
	}
5419
5420 525c9b73 Luiz Otavio O Souza
	$realif = get_failover_interface($interface, 'inet');
5421 cf73302f Phil Davis
	if (!$realif) {
5422 89f171b0 Ermal LUÇI
		return null;
5423 cf73302f Phil Davis
	}
5424 89f171b0 Ermal LUÇI
5425 ce31310e Chris Buechler
	if (substr($realif, 0, 4) == '_vip') {
5426 2a5960b0 Luiz Otavio O Souza
		return get_configured_vip_ipv4($realif);
5427 ce31310e Chris Buechler
	} else if (substr($realif, 0, 5) == '_lloc') {
5428 5eb59cee Luiz Otavio O Souza
		/* No link-local address for v4. */
5429
		return null;
5430 89953fe7 Chris Buechler
	}
5431 afb2de1b Ermal Lu?i
5432 5420820f Luiz Otavio O Souza
	if (is_array($config['interfaces'][$interface]) &&
5433
	    is_ipaddr($config['interfaces'][$interface]['ipaddr'])) {
5434
		return ($config['interfaces'][$interface]['ipaddr']);
5435
	}
5436
5437
	/*
5438
	 * Beaware that find_interface_ip() is our last option, it will
5439
	 * return the first IP it find on interface, not necessarily the
5440
	 * main IP address.
5441
	 */
5442 5e041d5f Scott Ullrich
	$curip = find_interface_ip($realif);
5443 cf73302f Phil Davis
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0")) {
5444 5e041d5f Scott Ullrich
		return $curip;
5445 cf73302f Phil Davis
	} else {
5446 8256f324 gnhb
		return null;
5447 cf73302f Phil Davis
	}
5448 5b237745 Scott Ullrich
}
5449
5450 337f8296 NewEraCracker
function get_interface_ipv6($interface = "wan", $flush = false, $linklocal_fallback = false) {
5451 479f0fda smos
	global $config;
5452 c4fc2eae Ermal
5453 2a5960b0 Luiz Otavio O Souza
	if (substr($interface, 0, 4) == '_vip') {
5454
		return get_configured_vip_ipv6($interface);
5455
	} else if (substr($interface, 0, 5) == '_lloc') {
5456
		return get_interface_linklocal($interface);
5457
	}
5458
5459 89f171b0 Ermal LUÇI
	$realif = get_failover_interface($interface, 'inet6');
5460 cf73302f Phil Davis
	if (!$realif) {
5461 89f171b0 Ermal LUÇI
		return null;
5462 cf73302f Phil Davis
	}
5463 89f171b0 Ermal LUÇI
5464 2a5960b0 Luiz Otavio O Souza
	if (substr($realif, 0, 4) == '_vip') {
5465
		return get_configured_vip_ipv6($realif);
5466
	} else if (substr($realif, 0, 5) == '_lloc') {
5467
		return get_interface_linklocal($realif);
5468 cf73302f Phil Davis
	}
5469 47593ac6 Seth Mos
5470 f253e928 Ermal
	if (is_array($config['interfaces'][$interface])) {
5471 420aa48b Ermal
		switch ($config['interfaces'][$interface]['ipaddr']) {
5472 cf73302f Phil Davis
			case 'pppoe':
5473
			case 'l2tp':
5474
			case 'pptp':
5475
			case 'ppp':
5476
				if ($config['interfaces'][$interface]['ipaddrv6'] == 'dhcp6') {
5477 5fb4bbfd doktornotor
					$realif = get_real_interface($interface, 'inet6', false);
5478 cf73302f Phil Davis
				}
5479
				break;
5480 420aa48b Ermal
		}
5481 d9901ff4 Chris Buechler
		if (is_ipaddrv6($config['interfaces'][$interface]['ipaddrv6'])) {
5482 5420820f Luiz Otavio O Souza
			return ($config['interfaces'][$interface]['ipaddrv6']);
5483 d9901ff4 Chris Buechler
		}
5484 f253e928 Ermal
	}
5485
5486 5420820f Luiz Otavio O Souza
	/*
5487
	 * Beaware that find_interface_ip() is our last option, it will
5488
	 * return the first IP it find on interface, not necessarily the
5489
	 * main IP address.
5490
	 */
5491 b6c1f22f Ermal
	$curip = find_interface_ipv6($realif, $flush);
5492 cf73302f Phil Davis
	if ($curip && is_ipaddrv6($curip) && ($curip != "::")) {
5493 47593ac6 Seth Mos
		return $curip;
5494 cf73302f Phil Davis
	} else {
5495 60802fad k-paulius
		/*
5496
		 * NOTE: On the case when only the prefix is requested,
5497
		 * the communication on WAN will be done over link-local.
5498
		 */
5499 337f8296 NewEraCracker
		if ($linklocal_fallback || (is_array($config['interfaces'][$interface]) && isset($config['interfaces'][$interface]['dhcp6prefixonly']))) {
5500 60802fad k-paulius
			$curip = find_interface_ipv6_ll($realif, $flush);
5501
			if ($curip && is_ipaddrv6($curip) && ($curip != "::")) {
5502
				return $curip;
5503
			}
5504
		}
5505 cf73302f Phil Davis
	}
5506 60802fad k-paulius
	return null;
5507 47593ac6 Seth Mos
}
5508
5509 a8f5790a Renato Botelho
function get_interface_linklocal($interface = "wan") {
5510 06886ae3 Ermal
5511 89f171b0 Ermal LUÇI
	$realif = get_failover_interface($interface, 'inet6');
5512 cf73302f Phil Davis
	if (!$realif) {
5513 89f171b0 Ermal LUÇI
		return null;
5514 cf73302f Phil Davis
	}
5515 89f171b0 Ermal LUÇI
5516 cf73302f Phil Davis
	if (substr($interface, 0, 4) == '_vip') {
5517 89f171b0 Ermal LUÇI
		$realif = get_real_interface($interface);
5518 cf73302f Phil Davis
	} else if (substr($interface, 0, 5) == '_lloc') {
5519 89f171b0 Ermal LUÇI
		$realif = get_real_interface(substr($interface, 5));
5520 cf73302f Phil Davis
	}
5521 58418355 smos
5522
	$curip = find_interface_ipv6_ll($realif);
5523 cf73302f Phil Davis
	if ($curip && is_ipaddrv6($curip) && ($curip != "::")) {
5524 58418355 smos
		return $curip;
5525 cf73302f Phil Davis
	} else {
5526 58418355 smos
		return null;
5527 cf73302f Phil Davis
	}
5528 58418355 smos
}
5529
5530 a8f5790a Renato Botelho
function get_interface_subnet($interface = "wan") {
5531 89f171b0 Ermal LUÇI
5532 d9901ff4 Chris Buechler
	if (substr($interface, 0, 4) == '_vip') {
5533 2a5960b0 Luiz Otavio O Souza
		return (get_configured_vip_subnetv4($interface));
5534 d9901ff4 Chris Buechler
	}
5535 89f171b0 Ermal LUÇI
5536 31b24870 Ermal Luçi
	$realif = get_real_interface($interface);
5537 d9901ff4 Chris Buechler
	if (!$realif) {
5538 2a5960b0 Luiz Otavio O Souza
		return (NULL);
5539 d9901ff4 Chris Buechler
	}
5540 e88fbe50 Ermal Lu?i
5541 5e041d5f Scott Ullrich
	$cursn = find_interface_subnet($realif);
5542 d9901ff4 Chris Buechler
	if (!empty($cursn)) {
5543 2a5960b0 Luiz Otavio O Souza
		return ($cursn);
5544 d9901ff4 Chris Buechler
	}
5545 31b24870 Ermal Luçi
5546 2a5960b0 Luiz Otavio O Souza
	return (NULL);
5547 31b24870 Ermal Luçi
}
5548
5549 a8f5790a Renato Botelho
function get_interface_subnetv6($interface = "wan") {
5550 c4fc2eae Ermal
5551 d9901ff4 Chris Buechler
	if (substr($interface, 0, 4) == '_vip') {
5552 2a5960b0 Luiz Otavio O Souza
		return (get_configured_vip_subnetv6($interface));
5553 d9901ff4 Chris Buechler
	} else if (substr($interface, 0, 5) == '_lloc') {
5554 89f171b0 Ermal LUÇI
		$interface = substr($interface, 5);
5555 d9901ff4 Chris Buechler
	}
5556 89f171b0 Ermal LUÇI
5557
	$realif = get_real_interface($interface, 'inet6');
5558 d9901ff4 Chris Buechler
	if (!$realif) {
5559 2a5960b0 Luiz Otavio O Souza
		return (NULL);
5560 d9901ff4 Chris Buechler
	}
5561 47593ac6 Seth Mos
5562
	$cursn = find_interface_subnetv6($realif);
5563 d9901ff4 Chris Buechler
	if (!empty($cursn)) {
5564 2a5960b0 Luiz Otavio O Souza
		return ($cursn);
5565 d9901ff4 Chris Buechler
	}
5566 47593ac6 Seth Mos
5567 2a5960b0 Luiz Otavio O Souza
	return (NULL);
5568 47593ac6 Seth Mos
}
5569
5570 52947718 Ermal Lu?i
/* return outside interfaces with a gateway */
5571
function get_interfaces_with_gateway() {
5572 77ccab82 Scott Ullrich
	global $config;
5573 52947718 Ermal Lu?i
5574
	$ints = array();
5575
5576
	/* loop interfaces, check config for outbound */
5577 cf73302f Phil Davis
	foreach ($config['interfaces'] as $ifdescr => $ifname) {
5578 77ccab82 Scott Ullrich
		switch ($ifname['ipaddr']) {
5579
			case "dhcp":
5580
			case "pppoe":
5581
			case "pptp":
5582 6d5446a2 Ermal
			case "l2tp":
5583 9cf1dbff Stuart Wyatt
			case "ppp":
5584 6d5446a2 Ermal
				$ints[$ifdescr] = $ifdescr;
5585 cf73302f Phil Davis
				break;
5586 77ccab82 Scott Ullrich
			default:
5587 6c07db48 Phil Davis
				if (substr($ifname['if'], 0, 4) == "ovpn" ||
5588 cf73302f Phil Davis
				    !empty($ifname['gateway'])) {
5589 6d5446a2 Ermal
					$ints[$ifdescr] = $ifdescr;
5590 cf73302f Phil Davis
				}
5591
				break;
5592 77ccab82 Scott Ullrich
		}
5593
	}
5594
	return $ints;
5595 52947718 Ermal Lu?i
}
5596
5597
/* return true if interface has a gateway */
5598
function interface_has_gateway($friendly) {
5599 6d5446a2 Ermal
	global $config;
5600 52947718 Ermal Lu?i
5601 6d5446a2 Ermal
	if (!empty($config['interfaces'][$friendly])) {
5602 43a22ee2 jim-p
		$ifname = &$config['interfaces'][$friendly];
5603 6d5446a2 Ermal
		switch ($ifname['ipaddr']) {
5604
			case "dhcp":
5605
			case "pppoe":
5606
			case "pptp":
5607
			case "l2tp":
5608 9cf1dbff Stuart Wyatt
			case "ppp":
5609 6d5446a2 Ermal
				return true;
5610
			break;
5611
			default:
5612 6c07db48 Phil Davis
				if (substr($ifname['if'], 0, 4) == "ovpn") {
5613 e9d7afeb Ermal
					return true;
5614 cf73302f Phil Davis
				}
5615 2700ef96 PiBa-NL
				$tunnelif = substr($ifname['if'], 0, 3);
5616 cf73302f Phil Davis
				if ($tunnelif == "gif" || $tunnelif == "gre") {
5617 471e7c3a jim-p
					if (find_interface_ip($ifname['if'])) {
5618
						return true;
5619
					}
5620 cf73302f Phil Davis
				}
5621
				if (!empty($ifname['gateway'])) {
5622 6d5446a2 Ermal
					return true;
5623 cf73302f Phil Davis
				}
5624 6d5446a2 Ermal
			break;
5625
		}
5626
	}
5627 52947718 Ermal Lu?i
5628
	return false;
5629
}
5630
5631 2feb85af Seth Mos
/* return true if interface has a gateway */
5632
function interface_has_gatewayv6($friendly) {
5633
	global $config;
5634
5635
	if (!empty($config['interfaces'][$friendly])) {
5636
		$ifname = &$config['interfaces'][$friendly];
5637
		switch ($ifname['ipaddrv6']) {
5638 67102344 smos
			case "slaac":
5639 2feb85af Seth Mos
			case "dhcp6":
5640 a11a839d smos
			case "6to4":
5641 d500e296 smos
			case "6rd":
5642
				return true;
5643 a11a839d smos
				break;
5644 2feb85af Seth Mos
			default:
5645 6c07db48 Phil Davis
				if (substr($ifname['if'], 0, 4) == "ovpn") {
5646 2feb85af Seth Mos
					return true;
5647 cf73302f Phil Davis
				}
5648 cdeaf91e Ermal
				$tunnelif = substr($ifname['if'], 0, 3);
5649 cf73302f Phil Davis
				if ($tunnelif == "gif" || $tunnelif == "gre") {
5650 471e7c3a jim-p
					if (find_interface_ipv6($ifname['if'])) {
5651
						return true;
5652
					}
5653 cf73302f Phil Davis
				}
5654
				if (!empty($ifname['gatewayv6'])) {
5655 2feb85af Seth Mos
					return true;
5656 cf73302f Phil Davis
				}
5657 a11a839d smos
				break;
5658 2feb85af Seth Mos
		}
5659
	}
5660
5661
	return false;
5662
}
5663
5664 a57b119e Bill Marquette
/****f* interfaces/is_altq_capable
5665
 * NAME
5666
 *   is_altq_capable - Test if interface is capable of using ALTQ
5667
 * INPUTS
5668
 *   $int            - string containing interface name
5669
 * RESULT
5670
 *   boolean         - true or false
5671
 ******/
5672
5673 eba938e3 Scott Ullrich
function is_altq_capable($int) {
5674 1c3ddd9e Renato Botelho
	/* Per:
5675 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
5676 1c3ddd9e Renato Botelho
	 * Only the following drivers have ALTQ support
5677 56effb56 Chris Buechler
	 * 20150328 - removed wireless drivers - ath, awi, bwn, iwi, ipw, ral, rum, run, wi - for now. redmine #4406
5678 1c3ddd9e Renato Botelho
	 */
5679 56effb56 Chris Buechler
	$capable = array("ae", "age", "alc", "ale", "an", "aue", "axe", "bce",
5680 3d8e954b Chris Buechler
			"bfe", "bge", "bridge", "cas", "dc", "de", "ed", "em", "ep", "epair", "et", "fxp", "gem",
5681 af769801 jim-p
			"hme", "hn", "igb", "ix", "jme", "le", "lem", "msk", "mxge", "my", "nfe",
5682 56effb56 Chris Buechler
			"nge", "npe", "nve", "re", "rl", "sf", "sge", "sis", "sk",
5683
			"ste", "stge", "ti", "txp", "udav", "ural", "vge", "vmx", "vr", "vte", "xl",
5684 febca7e8 Ermal
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng",
5685 cf205dca Ermal
			"l2tp", "ppp", "vtnet");
5686 a57b119e Bill Marquette
5687 2ccac125 Renato Botelho
	$int_family = remove_ifindex($int);
5688 a57b119e Bill Marquette
5689 cf73302f Phil Davis
	if (in_array($int_family, $capable)) {
5690 1c3ddd9e Renato Botelho
		return true;
5691 cf73302f Phil Davis
	} else if (stristr($int, "l2tp")) { /* VLANs are named $parent_$vlan now */
5692 dbe67167 Ermal
		return true;
5693 cf73302f Phil Davis
	} else if (stristr($int, "_vlan")) { /* VLANs are named $parent_$vlan now */
5694 7e627719 Ermal
		return true;
5695 cf73302f Phil Davis
	} else if (stristr($int, "_wlan")) { /* WLANs are named $parent_$wlan now */
5696 2f3446db Ermal Lu?i
		return true;
5697 cf73302f Phil Davis
	} else {
5698 1c3ddd9e Renato Botelho
		return false;
5699 cf73302f Phil Davis
	}
5700 a57b119e Bill Marquette
}
5701
5702 52947718 Ermal Lu?i
/****f* interfaces/is_interface_wireless
5703
 * NAME
5704
 *   is_interface_wireless - Returns if an interface is wireless
5705
 * RESULT
5706
 *   $tmp       - Returns if an interface is wireless
5707
 ******/
5708
function is_interface_wireless($interface) {
5709 1c3ddd9e Renato Botelho
	global $config, $g;
5710
5711
	$friendly = convert_real_interface_to_friendly_interface_name($interface);
5712 cf73302f Phil Davis
	if (!isset($config['interfaces'][$friendly]['wireless'])) {
5713 1c3ddd9e Renato Botelho
		if (preg_match($g['wireless_regex'], $interface)) {
5714 cf73302f Phil Davis
			if (isset($config['interfaces'][$friendly])) {
5715 1c3ddd9e Renato Botelho
				$config['interfaces'][$friendly]['wireless'] = array();
5716 cf73302f Phil Davis
			}
5717 1c3ddd9e Renato Botelho
			return true;
5718
		}
5719
		return false;
5720 cf73302f Phil Davis
	} else {
5721 1c3ddd9e Renato Botelho
		return true;
5722 cf73302f Phil Davis
	}
5723 52947718 Ermal Lu?i
}
5724
5725 eba938e3 Scott Ullrich
function get_wireless_modes($interface) {
5726 d8c67d69 Scott Ullrich
	/* return wireless modes and channels */
5727 92f7d37d Ermal Luçi
	$wireless_modes = array();
5728
5729 5357f386 Erik Fonnesbeck
	$cloned_interface = get_real_interface($interface);
5730 1b773d20 Ermal Lu?i
5731 cf73302f Phil Davis
	if ($cloned_interface && is_interface_wireless($cloned_interface)) {
5732 1b773d20 Ermal Lu?i
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
5733
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
5734 1de74081 Ermal Lu?i
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
5735 d8c67d69 Scott Ullrich
5736 4b0e71db Scott Ullrich
		$interface_channels = "";
5737 d8c67d69 Scott Ullrich
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
5738
		$interface_channel_count = count($interface_channels);
5739
5740
		$c = 0;
5741 a8f5790a Renato Botelho
		while ($c < $interface_channel_count) {
5742 d8c67d69 Scott Ullrich
			$channel_line = explode(",", $interface_channels["$c"]);
5743
			$wireless_mode = trim($channel_line[0]);
5744
			$wireless_channel = trim($channel_line[1]);
5745 cf73302f Phil Davis
			if (trim($wireless_mode) != "") {
5746 4066776d Scott Ullrich
				/* if we only have 11g also set 11b channels */
5747 cf73302f Phil Davis
				if ($wireless_mode == "11g") {
5748
					if (!isset($wireless_modes["11b"])) {
5749 1ae54336 Erik Fonnesbeck
						$wireless_modes["11b"] = array();
5750 cf73302f Phil Davis
					}
5751
				} else if ($wireless_mode == "11g ht") {
5752
					if (!isset($wireless_modes["11b"])) {
5753 1ae54336 Erik Fonnesbeck
						$wireless_modes["11b"] = array();
5754 cf73302f Phil Davis
					}
5755
					if (!isset($wireless_modes["11g"])) {
5756 1ae54336 Erik Fonnesbeck
						$wireless_modes["11g"] = array();
5757 cf73302f Phil Davis
					}
5758 39c1349c Erik Fonnesbeck
					$wireless_mode = "11ng";
5759 cf73302f Phil Davis
				} else if ($wireless_mode == "11a ht") {
5760
					if (!isset($wireless_modes["11a"])) {
5761 1ae54336 Erik Fonnesbeck
						$wireless_modes["11a"] = array();
5762 cf73302f Phil Davis
					}
5763 39c1349c Erik Fonnesbeck
					$wireless_mode = "11na";
5764 4066776d Scott Ullrich
				}
5765
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
5766
			}
5767 d8c67d69 Scott Ullrich
			$c++;
5768
		}
5769
	}
5770 4066776d Scott Ullrich
	return($wireless_modes);
5771 d8c67d69 Scott Ullrich
}
5772
5773 f4094f0d Erik Fonnesbeck
/* return channel numbers, frequency, max txpower, and max regulation txpower */
5774
function get_wireless_channel_info($interface) {
5775
	$wireless_channels = array();
5776
5777 5357f386 Erik Fonnesbeck
	$cloned_interface = get_real_interface($interface);
5778 f4094f0d Erik Fonnesbeck
5779 cf73302f Phil Davis
	if ($cloned_interface && is_interface_wireless($cloned_interface)) {
5780 f4094f0d Erik Fonnesbeck
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
5781
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
5782
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
5783
5784
		$interface_channels = "";
5785
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
5786
5787
		foreach ($interface_channels as $channel_line) {
5788
			$channel_line = explode(",", $channel_line);
5789 cf73302f Phil Davis
			if (!isset($wireless_channels[$channel_line[0]])) {
5790 f4094f0d Erik Fonnesbeck
				$wireless_channels[$channel_line[0]] = $channel_line;
5791 cf73302f Phil Davis
			}
5792 f4094f0d Erik Fonnesbeck
		}
5793
	}
5794
	return($wireless_channels);
5795
}
5796
5797 89c8934f Luiz Otavio O Souza
function set_interface_mtu($interface, $mtu) {
5798
5799
	/* LAGG interface must be destroyed and re-created to change MTU */
5800
	if (substr($interface, 0, 4) == 'lagg') {
5801
		if (isset($config['laggs']['lagg']) &&
5802
		    is_array($config['laggs']['lagg'])) {
5803
			foreach ($config['laggs']['lagg'] as $lagg) {
5804
				if ($lagg['laggif'] == $interface) {
5805
					interface_lagg_configure($lagg);
5806
					break;
5807
				}
5808
			}
5809
		}
5810
	} else {
5811
		pfSense_interface_mtu($interface, $mtu);
5812
	}
5813
}
5814
5815 52947718 Ermal Lu?i
/****f* interfaces/get_interface_mtu
5816
 * NAME
5817
 *   get_interface_mtu - Return the mtu of an interface
5818
 * RESULT
5819
 *   $tmp       - Returns the mtu of an interface
5820
 ******/
5821
function get_interface_mtu($interface) {
5822 3d3dd668 Ermal LUÇI
	$mtu = pfSense_interface_getmtu($interface);
5823 1c3ddd9e Renato Botelho
	return $mtu['mtu'];
5824 52947718 Ermal Lu?i
}
5825
5826 eba938e3 Scott Ullrich
function get_interface_mac($interface) {
5827 7d6076f3 Ermal Lu?i
5828 3f70e618 Ermal Lu?i
	$macinfo = pfSense_get_interface_addresses($interface);
5829
	return $macinfo["macaddr"];
5830 f2ba47f8 Ermal Lu?i
}
5831
5832
/****f* pfsense-utils/generate_random_mac_address
5833
 * NAME
5834
 *   generate_random_mac - generates a random mac address
5835
 * INPUTS
5836
 *   none
5837
 * RESULT
5838
 *   $mac - a random mac address
5839
 ******/
5840
function generate_random_mac_address() {
5841 1c3ddd9e Renato Botelho
	$mac = "02";
5842 6c07db48 Phil Davis
	for ($x = 0; $x < 5; $x++) {
5843 1c3ddd9e Renato Botelho
		$mac .= ":" . dechex(rand(16, 255));
5844 cf73302f Phil Davis
	}
5845 1c3ddd9e Renato Botelho
	return $mac;
5846 53c82ef9 Scott Ullrich
}
5847 b7ec2b9e Scott Ullrich
5848 52947718 Ermal Lu?i
/****f* interfaces/is_jumbo_capable
5849
 * NAME
5850
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
5851
 * INPUTS
5852
 *   $int             - string containing interface name
5853
 * RESULT
5854
 *   boolean          - true or false
5855
 ******/
5856 47ee6926 Ermal
function is_jumbo_capable($iface) {
5857
	$iface = trim($iface);
5858
	$capable = pfSense_get_interface_addresses($iface);
5859 a687f866 Namezero
5860 cf73302f Phil Davis
	if (isset($capable['caps']['vlanmtu'])) {
5861 1c3ddd9e Renato Botelho
		return true;
5862 cf73302f Phil Davis
	}
5863 a687f866 Namezero
5864 21e2561f Chris Buechler
	// hack for some lagg modes missing vlanmtu, but work fine w/VLANs
5865 cf73302f Phil Davis
	if (substr($iface, 0, 4) == "lagg") {
5866 21e2561f Chris Buechler
		return true;
5867 cf73302f Phil Davis
	}
5868 21e2561f Chris Buechler
5869 47ee6926 Ermal
	return false;
5870 52947718 Ermal Lu?i
}
5871
5872 70e46e62 Ermal
function interface_setup_pppoe_reset_file($pppif, $iface="") {
5873 55f3ca1d gnhb
	global $g;
5874 70e46e62 Ermal
5875 5c8e8a17 gnhb
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
5876 766bd6d0 gnhb
5877 cf73302f Phil Davis
	if (!empty($iface) && !empty($pppif)) {
5878 7673cdb5 Ermal
		$cron_cmd = <<<EOD
5879
#!/bin/sh
5880
/usr/local/sbin/pfSctl -c 'interface reload {$iface}'
5881 70e46e62 Ermal
/usr/bin/logger -t {$pppif} "PPPoE periodic reset executed on {$iface}"
5882 7673cdb5 Ermal
5883
EOD;
5884
5885 70e46e62 Ermal
		@file_put_contents($cron_file, $cron_cmd);
5886
		chmod($cron_file, 0755);
5887 55f3ca1d gnhb
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
5888 cf73302f Phil Davis
	} else {
5889 766bd6d0 gnhb
		unlink_if_exists($cron_file);
5890 cf73302f Phil Davis
	}
5891 b7ec2b9e Scott Ullrich
}
5892
5893 56da23dc Ermal
function get_interface_default_mtu($type = "ethernet") {
5894
	switch ($type) {
5895 cf73302f Phil Davis
		case "gre":
5896
			return 1476;
5897
			break;
5898
		case "gif":
5899
			return 1280;
5900
			break;
5901
		case "tun":
5902
		case "vlan":
5903
		case "tap":
5904
		case "ethernet":
5905
		default:
5906
			return 1500;
5907
			break;
5908 56da23dc Ermal
	}
5909
5910
	/* Never reached */
5911
	return 1500;
5912
}
5913
5914 dd62256f Pierre POMES
function get_vip_descr($ipaddress) {
5915
	global $config;
5916
5917
	foreach ($config['virtualip']['vip'] as $vip) {
5918
		if ($vip['subnet'] == $ipaddress) {
5919
			return ($vip['descr']);
5920
		}
5921
	}
5922
	return "";
5923
}
5924
5925 d368b334 jim-p
function interfaces_staticarp_configure($if) {
5926
	global $config, $g;
5927 cf73302f Phil Davis
	if (isset($config['system']['developerspew'])) {
5928 d368b334 jim-p
		$mt = microtime();
5929
		echo "interfaces_staticarp_configure($if) being called $mt\n";
5930
	}
5931
5932
	$ifcfg = $config['interfaces'][$if];
5933
5934 cf73302f Phil Davis
	if (empty($if) || empty($ifcfg['if']) || !isset($ifcfg['enable'])) {
5935 d368b334 jim-p
		return 0;
5936 cf73302f Phil Davis
	}
5937 d368b334 jim-p
5938
	/* Enable staticarp, if enabled */
5939 cf73302f Phil Davis
	if (isset($config['dhcpd'][$if]['staticarp'])) {
5940 086cf944 Phil Davis
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp ");
5941 d368b334 jim-p
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
5942
		if (is_array($config['dhcpd'][$if]['staticmap'])) {
5943
			foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
5944
				mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
5945
			}
5946
		}
5947
	} else {
5948 086cf944 Phil Davis
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp ");
5949 d368b334 jim-p
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
5950 c06e4f69 Ermal
		if (is_array($config['dhcpd'][$if]) && is_array($config['dhcpd'][$if]['staticmap'])) {
5951 25c1ebd5 N0YB
			foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
5952
				if (isset($arpent['arp_table_static_entry'])) {
5953
					mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
5954
				}
5955
			}
5956
		}
5957 d368b334 jim-p
	}
5958
5959
	return 0;
5960
}
5961
5962 909de400 Ermal
function get_failover_interface($interface, $family = "all") {
5963 bf001dec smos
	global $config;
5964 06886ae3 Ermal
5965 e90c833a smos
	/* shortcut to get_real_interface if we find it in the config */
5966 06886ae3 Ermal
	if (is_array($config['interfaces'][$interface])) {
5967
		return get_real_interface($interface, $family);
5968 e90c833a smos
	}
5969
5970 bf001dec smos
	/* compare against gateway groups */
5971
	$a_groups = return_gateway_groups_array();
5972 06886ae3 Ermal
	if (is_array($a_groups[$interface])) {
5973 bf001dec smos
		/* we found a gateway group, fetch the interface or vip */
5974 cf73302f Phil Davis
		if (!empty($a_groups[$interface][0]['vip'])) {
5975 06886ae3 Ermal
			return $a_groups[$interface][0]['vip'];
5976 cf73302f Phil Davis
		} else {
5977 06886ae3 Ermal
			return $a_groups[$interface][0]['int'];
5978 cf73302f Phil Davis
		}
5979 bf001dec smos
	}
5980
	/* fall through to get_real_interface */
5981 06886ae3 Ermal
	/* XXX: Really needed? */
5982
	return get_real_interface($interface, $family);
5983 bf001dec smos
}
5984
5985 2ccac125 Renato Botelho
function remove_ifindex($ifname) {
5986
	return preg_replace("/[0-9]+$/", "", $ifname);
5987
}
5988
5989 6a7dd9bb Ermal
?>