Project

General

Profile

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