Project

General

Profile

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