Project

General

Profile

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