Project

General

Profile

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