Project

General

Profile

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