Project

General

Profile

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