Project

General

Profile

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