Project

General

Profile

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