Project

General

Profile

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