Project

General

Profile

Download (19.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
  Copyright (C) 2008 Bill Marquette, Seth Mos
4
  Copyright (C) 2010 Ermal Lu?i
5
  All rights reserved.
6

    
7
  Redistribution and use in source and binary forms, with or without
8
  modification, are permitted provided that the following conditions are met:
9

    
10
  1. Redistributions of source code must retain the above copyright notice,
11
  this list of conditions and the following disclaimer.
12

    
13
  2. Redistributions in binary form must reproduce the above copyright
14
  notice, this list of conditions and the following disclaimer in the
15
  documentation and/or other materials provided with the distribution.
16

    
17
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19
  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20
  AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
  POSSIBILITY OF SUCH DAMAGE.
27

    
28
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/sbin/route	/usr/local/sbin/apinger
29
	pfSense_MODULE:	routing
30

    
31
 */
32

    
33
/*
34
 * Creates monitoring configuration file and
35
 * adds apropriate static routes.
36
 */
37
function setup_gateways_monitor() {
38
	global $config, $g;
39

    
40
	$gateways_arr = return_gateways_array();
41
	if (!is_array($gateways_arr)) {
42
		log_error("No gateways to monitor. Apinger will not be run.");
43
		killbypid("{$g['varrun_path']}/apinger.pid");
44
		@unlink("{$g['tmp_path']}/apinger.status");
45
		return;
46
	}
47

    
48
	/* Default settings. Probably should move to globals.inc? */
49
	$a_settings = array();
50
	$a_settings['latencylow'] = "200";
51
	$a_settings['latencyhigh'] = "500";
52
	$a_settings['losslow'] = "10";
53
	$a_settings['losshigh'] = "20";
54

    
55
	$fd = fopen("{$g['varetc_path']}/apinger.conf", "w");
56
	$apingerconfig = <<<EOD
57

    
58
# pfSense apinger configuration file. Automatically Generated!
59

    
60
## User and group the pinger should run as
61
user "root"
62
group "wheel"
63

    
64
## Mailer to use (default: "/usr/lib/sendmail -t")
65
#mailer "/var/qmail/bin/qmail-inject" 
66

    
67
## Location of the pid-file (default: "/var/run/apinger.pid")
68
pid_file "{$g['varrun_path']}/apinger.pid"
69

    
70
## Format of timestamp (%s macro) (default: "%b %d %H:%M:%S")
71
#timestamp_format "%Y%m%d%H%M%S"
72

    
73
status {
74
	## File where the status information whould be written to
75
	file "{$g['tmp_path']}/apinger.status"
76
	## Interval between file updates
77
	## when 0 or not set, file is written only when SIGUSR1 is received
78
	interval 5s
79
}
80

    
81
########################################
82
# RRDTool status gathering configuration
83
# Interval between RRD updates
84
rrd interval 60s;
85

    
86
## These parameters can be overriden in a specific alarm configuration
87
alarm default { 
88
	command on "/usr/local/sbin/pfSctl -c 'filter reload'"
89
	command off "/usr/local/sbin/pfSctl -c 'filter reload'"
90
	combine 10s
91
}
92

    
93
## "Down" alarm definition. 
94
## This alarm will be fired when target doesn't respond for 30 seconds.
95
alarm down "down" {
96
	time 10s
97
}
98

    
99
## "Delay" alarm definition. 
100
## This alarm will be fired when responses are delayed more than 200ms
101
## it will be canceled, when the delay drops below 100ms
102
alarm delay "delay" {
103
	delay_low {$a_settings['latencylow']}ms
104
	delay_high {$a_settings['latencyhigh']}ms
105
}
106

    
107
## "Loss" alarm definition. 
108
## This alarm will be fired when packet loss goes over 20%
109
## it will be canceled, when the loss drops below 10%
110
alarm loss "loss" {
111
	percent_low {$a_settings['losslow']}
112
	percent_high {$a_settings['losshigh']}
113
}
114

    
115
target default {
116
	## How often the probe should be sent	
117
	interval 1s
118
	
119
	## How many replies should be used to compute average delay 
120
	## for controlling "delay" alarms
121
	avg_delay_samples 10
122
	
123
	## How many probes should be used to compute average loss
124
	avg_loss_samples 50
125

    
126
	## The delay (in samples) after which loss is computed
127
	## without this delays larger than interval would be treated as loss
128
	avg_loss_delay_samples 20
129

    
130
	## Names of the alarms that may be generated for the target
131
	alarms "down","delay","loss"
132

    
133
	## Location of the RRD
134
	#rrd file "{$g['vardb_path']}/rrd/apinger-%t.rrd"
135
}
136

    
137
EOD;
138

    
139
	foreach($gateways_arr as $name => $gateway) {
140
		/* Do not monitor if such was requested */
141
		if (isset($gateway['monitor_disable']))
142
			continue;
143
		if (empty($gateway['monitor']) || !is_ipaddr($gateway['monitor'])) {
144
			if (is_ipaddr($gateway['gateway']))
145
				$gateway['monitor'] = $gateway['gateway'];
146
			else /* No chance to get an ip to monitor skip target. */
147
				continue;
148
		}
149

    
150
		/* Interface ip is needed since apinger will bind a socket to it. */
151
		if (is_ipaddrv4($gateway['gateway'])) {
152
			$gwifip = find_interface_ip($gateway['interface'], true);
153
		}
154
		if (is_ipaddrv6($gateway['gateway'])) {
155
			$gwifip = find_interface_ipv6($gateway['interface'], true);
156
		}
157
		if (!is_ipaddr($gwifip))
158
			continue; //Skip this target
159

    
160
		$apingercfg = "target \"{$gateway['monitor']}\" {\n";
161
		$apingercfg .= "	description \"{$name}\"\n";
162
		$apingercfg .= "	srcip \"{$gwifip}\"\n";
163
		$alarms = "";
164
		$alarmscfg = "";
165
		$override = false;
166
		if (!empty($gateway['lowloss'])) {
167
			$alarmscfg .= "alarm loss \"{$name}loss\" {\n";
168
			$alarmscfg .= "\tpercent_low {$gateway['losslow']}\n";
169
       			$alarmscfg .= "\tpercent_high {$gateway['losshigh']}\n";
170
			$alarmscfg .= "}\n";
171
			$alarms .= "\"{$name}loss\"";
172
			$override = true;
173
		} else {
174
			if ($override == true)
175
				$alarms .= ",";
176
			$alarms .= "\"loss\"";
177
			$override = true;
178
		}
179
		if (!empty($gateway['latencylow'])) {
180
			$alarmscfg .= "alarm delay \"{$name}delay\" {\n";
181
			$alarmscfg .= "\tdelay_low {$gateway['latencylow']}ms\n";
182
			$alarmscfg .= "\tdelay_high {$gateway['latencyhigh']}ms\n";
183
			$alarmscfg .= "}\n";
184
			if ($override == true)
185
				$alarms .= ",";
186
			$alarms .= "\"{$name}delay\"";
187
			$override = true;
188
		} else {
189
			if ($override == true)
190
				$alarms .= ",";
191
			$alarms .= "\"delay\"";
192
			$override = true;
193
		}
194
		if (!empty($gateway['down'])) {
195
			$alarmscfg .= "alarm down \"{$name}down\" {\n";
196
			$alarmscfg .= "\ttime {$gateway['down']}s\n";
197
			$alarmscfg .= "}\n";
198
			if ($override == true)
199
				$alarms .= ",";
200
			$alarms .= "\"{$name}down\"";
201
			$override = true;
202
		} else {
203
			if ($override == true)
204
				$alarms .= ",";
205
			$alarms .= "\"down\"";
206
			$override = true;
207
		}
208
		if ($override == true)
209
			$apingercfg .= "\talarms override {$alarms};\n";
210

    
211
		$apingercfg .= "	rrd file \"{$g['vardb_path']}/rrd/{$gateway['name']}-quality.rrd\"\n";
212
		$apingercfg .= "}\n";
213
		$apingercfg .= "\n";
214
		/*
215
		 * If the gateway is the same as the monitor we do not add a
216
		 * route as this will break the routing table.
217
		 * Add static routes for each gateway with their monitor IP
218
		 * not strictly necessary but is a added level of protection.
219
		 */
220
		if (is_ipaddr($gateway['gateway']) && $gateway['monitor'] != $gateway['gateway']) {
221
			log_error(sprintf(gettext('Removing static route for monitor %1$s and adding a new route through %2$s'), $gateway['monitor'], $gateway['gateway']));
222
			mwexec("/sbin/route change -host " . escapeshellarg($gateway['monitor']) .
223
				" " . escapeshellarg($gateway['gateway']), true);
224
		}
225

    
226
		$apingerconfig .= $alarmscfg;
227
		$apingerconfig .= $apingercfg;
228
	}
229
	fwrite($fd, $apingerconfig);
230
	fclose($fd);
231

    
232
	killbypid("{$g['varrun_path']}/apinger.pid");
233
	if (is_dir("{$g['tmp_path']}"))
234
		chmod("{$g['tmp_path']}", 01777);
235
	if (!is_dir("{$g['vardb_path']}/rrd"))
236
		mkdir("{$g['vardb_path']}/rrd", 0775);
237

    
238
	@chown("{$g['vardb_path']}/rrd", "nobody");
239

    
240
	/* start a new apinger process */
241
	@unlink("{$g['tmp_path']}/apinger.status");
242
	sleep(1);
243
	mwexec_bg("/usr/local/sbin/apinger -c {$g['varetc_path']}/apinger.conf");
244

    
245
	return 0;
246
}
247

    
248
/* return the status of the apinger targets as a array */
249
function return_gateways_status($byname = false) {
250
	global $config, $g;
251

    
252
	$apingerstatus = array();
253
	if (file_exists("{$g['tmp_path']}/apinger.status")) {
254
		$apingerstatus = file("{$g['tmp_path']}/apinger.status");
255
	}
256

    
257
	$status = array();
258
	foreach($apingerstatus as $line) {
259
		$info = explode("|", $line);
260
		if ($byname == false)
261
			$target = $info[0];
262
		else
263
			$target = $info[2];
264
		$status[$target]['monitorip'] = $info[0];
265
		$status[$target]['srcip'] = $info[1];
266
		$status[$target]['name'] = $info[2];
267
		$status[$target]['lastcheck'] = $info[5] ? date('r', $info[5]) : date('r');
268
		$status[$target]['delay'] = empty($info[6]) ? 0 : $info[6];
269
		$status[$target]['loss'] = empty($info[7]) ? "0.0%" : $info[7] . "";
270
		$status[$target]['status'] = trim($info[8]);
271
	}
272

    
273
	return($status);
274
}
275

    
276
/* Return all configured gateways on the system */
277
function return_gateways_array($disabled = false) {
278
	global $config, $g;
279

    
280
	$gateways_arr = array();
281

    
282
	$i = 0;
283
	/* Process/add all the configured gateways. */
284
	if (is_array($config['gateways']['gateway_item'])) {
285
		foreach($config['gateways']['gateway_item'] as $gateway) {
286
			if(empty($gateway['gateway']) || $gateway['gateway'] == "dynamic") {
287
				$gateway['gateway'] = get_interface_gateway($gateway['interface']);
288
				/* no IP address found, set to dynamic */
289
				if(! is_ipaddr($gateway['gateway']))
290
					$gateway['gateway'] = "dynamic";
291
				$gateway['dynamic'] = true;
292
			}
293
			if (isset($gateway['monitor_disable']))
294
				$gateway['monitor_disable'] = true;
295
			else if (empty($gateway['monitor']))
296
				$gateway['monitor'] = $gateway['gateway'];
297

    
298
			$gateway['friendlyiface'] = $gateway['interface'];
299
			$gateway['interface'] = get_real_interface($gateway['interface']);
300
			/* FIXME: Should this be enabled.
301
			 * Some interface like wan might be default but have no info recorded 
302
			 * the config.
303
			if ($gateway['friendlyiface'] == "wan" && !isset($gateway['defaultgw'])) {
304
				if (file_exists("{$g['tmp_path']}/{$gateway['interface']}_defaultgw"))
305
					$gateway['defaultgw'] = true;
306
			}
307
			 */
308
			/* include the gateway index as the attribute */
309
			$gateway['attribute'] = $i;
310

    
311
			$gateways_arr[$gateway['name']] = $gateway;
312
			$i++;
313
		}
314
	} 
315

    
316
	/* Loop through all interfaces with a gateway and add it to a array */
317
	if ($disabled == false)
318
		$iflist = get_configured_interface_with_descr();
319
	else
320
		$iflist = get_configured_interface_with_descr(false, true);
321

    
322
	/* Process/add dynamic gateways. */
323
	foreach($iflist as $ifname => $friendly ) {
324
		if(! interface_has_gateway($ifname))
325
			continue;
326

    
327
		if (empty($config['interfaces'][$ifname]))
328
			continue;
329

    
330
		$ifcfg = &$config['interfaces'][$ifname];
331
		if (!empty($ifcfg['ipaddr']) && is_ipaddr($ifcfg['ipaddr']))
332
			continue;
333

    
334
		$gateway = array();
335
		$gateway['dynamic'] = false;
336
		$gateway['gateway'] = get_interface_gateway($ifname, $gateway['dynamic']);
337
		$gateway['interface'] = get_real_interface($ifname);
338
		$gateway['friendlyiface'] = $ifname;
339
		$gateway['name'] = $friendly;
340
		$gateway['attribute'] = "system";
341
	
342
		if ($gateway['dynamic'] === "default") {
343
			$gateway['defaultgw'] = true;
344
			$gateway['dynamic'] = true;
345
		}
346
		/* Loopback dummy for dynamic interfaces without a IP */
347
		if (!is_ipaddr($gateway['gateway']) && $gateway['dynamic'] == true)
348
			$gateway['gateway'] = "dynamic";
349

    
350
		/* automatically skip known static and dynamic gateways we have a array entry for */
351
		foreach($gateways_arr as $gateway_item) {
352
			if (($ifname == $gateway_item['friendlyiface'] && $friendly == $gateway_item['name']) ||
353
				($ifname == $gateway_item['friendlyiface'] && $gateway_item['dynamic'] == true))
354
					continue 2;
355
		}
356

    
357
		if (is_ipaddr($gateway['gateway']))
358
			$gateway['monitor'] = $gateway['gateway'];
359

    
360
		$gateway['descr'] = "Interface {$friendly} Dynamic Gateway";
361
		$gateways_arr[$friendly] = $gateway;
362
	}
363

    
364
	return($gateways_arr);
365
}
366

    
367
/*
368
 * Return an array with all gateway groups with name as key
369
 * All gateway groups will be processed before returning the array.
370
 */
371
function return_gateway_groups_array() {
372
	global $config, $g;
373

    
374
	/* fetch the current gateways status */
375
	$gateways_status = return_gateways_status(true);
376
	$gateways_arr = return_gateways_array();
377
	$gateway_groups_array = array();
378

    
379
	if (isset($config['system']['gw_switch_default'])) {
380
		/* 
381
		 * NOTE: The code below is meant to replace the default gateway when it goes down.
382
		 *	This facilitates services running on pfSense itself and are not handled by a PBR to continue working.
383
		 */
384
		$upgw = "";
385
		$dfltgwdown = false;
386
		$dfltgwfound = false;
387
		foreach ($gateways_arr as $gwname => $gwsttng) {
388
			if (isset($gwsttng['defaultgw'])) {
389
				$dfltgwfound = true;
390
				$dfltgwname = $gwname;
391
				if (!isset($gwsttng['monitor_disable']) && stristr($gateways_status[$gwname]['status'], "down"))
392
					$dfltgwdown = true;
393
			}
394
			/* Keep a record of the last up gateway */
395
			if (empty($upgw) && (isset($gwsttng['monitor_disable']) || !stristr($gateways_status[$gwname]['status'], "down")))
396
				$upgw = $gwname;
397
			if ($dfltgwdown == true && !empty($upgw))
398
				break;
399
		}
400
		if ($dfltgwfound == false) {
401
			$gwname = convert_friendly_interface_to_friendly_descr("wan");
402
			if (!empty($gateways_status[$gwname]) && stristr($gateways_status[$gwname]['status'], "down"))
403
				$dfltgwdown = true;
404
		}
405
		if ($dfltgwdown == true && !empty($upgw)) {
406
			if ($gateways_arr[$upgw]['gateway'] == "dynamic")
407
				$gateways_arr[$upgw]['gateway'] = get_interface_gateway($gateways_arr[$upgw]['friendlyiface']);
408
			if (is_ipaddr($gateways_arr[$upgw]['gateway'])) {
409
				log_error("Default gateway down setting {$upgw} as default!");
410
				mwexec("/sbin/route change -inet default {$gateways_arr[$upgw]['gateway']}");
411
			}
412
		} else {
413
			$defaultgw = trim(`/sbin/route -n get -inet default | /usr/bin/grep gateway | /usr/bin/sed 's/gateway://g'`, " \n");
414
			if ($defaultgw != $gateways_arr[$dfltgwname]['gateway'])
415
				mwexec("/sbin/route change -inet default {$gateways_arr[$dfltgwname]['gateway']}");
416
		}
417
				
418
		unset($upgw, $dfltgwfound, $dfltgwdown, $gwname, $gwsttng);
419
	}
420

    
421
	if (is_array($config['gateways']['gateway_group'])) {
422
		foreach($config['gateways']['gateway_group'] as $group) {
423
			/* create array with group gateways members seperated by tier */
424
			$tiers = array();
425
			$backupplan = array();
426
			foreach($group['item'] as $item) {
427
				$itemsplit = explode("|", $item);
428
				$tier = $itemsplit[1];
429
				$gwname = $itemsplit[0];
430

    
431
				/* Do it here rather than reiterating again the group in case no member is up. */
432
				$backupplan[$tier][] = $gwname;
433

    
434
				/* check if the gateway is available before adding it to the array */
435
				if (!empty($gateways_status[$gwname])) {
436
					$status = $gateways_status[$gwname];
437
					$gwdown = false;
438
					if (stristr($status['status'], "down")) {
439
						$msg = sprintf(gettext("MONITOR: %s is down, removing from routing group"), $gwname);
440
						$gwdown = true;
441
					} else if (stristr($status['status'], "loss") && strstr($group['trigger'], "loss")) {
442
						/* packet loss */
443
						$msg = sprintf(gettext("MONITOR: %s has packet loss, removing from routing group"), $gwname);
444
						$gwdown = true;
445
					} else if (stristr($status['status'], "delay") && strstr($group['trigger'] , "latency")) {
446
						/* high latency */
447
						$msg = sprintf(gettext("MONITOR: %s has high latency, removing from routing group"), $gwname);
448
						$gwdown = true;
449
					}
450
					if ($gwdown == true) {
451
						log_error($msg);
452
						notify_via_growl($msg);
453
						notify_via_smtp($msg);
454
					} else
455
						/* Online add member */
456
						$tiers[$tier][] = $gwname;
457
				} else if (isset($gateways_arr[$gwname]['monitor_disable']))
458
					$tiers[$tier][] = $gwname;
459
			}
460
			$tiers_count = count($tiers);
461
			if($tiers_count == 0) {
462
				/* Oh dear, we have no members! Engage Plan B */
463
				if (!$g['booting']) {
464
					$msg = gettext("Gateways status could not be determined, considering all as up/active.");
465
					log_error($msg);
466
					notify_via_growl($msg);
467
					notify_via_smtp($msg);
468
				}
469
				$tiers = $backupplan;
470
			}
471
			/* sort the tiers array by the tier key */
472
			ksort($tiers);
473

    
474
			/* we do not really foreach the tiers as we stop after the first tier */
475
			foreach($tiers as $tier) {
476
				/* process all gateways in this tier */
477
				foreach($tier as $member) {
478
					/* determine interface gateway */
479
					if (isset($gateways_arr[$member])) {
480
						$gateway = $gateways_arr[$member];
481
						$int = $gateway['interface'];
482
						$gatewayip = "";
483
						if(is_ipaddr($gateway['gateway'])) 
484
							$gatewayip = $gateway['gateway'];
485
						else if ($int <> "")
486
							$gatewayip = get_interface_gateway($gateway['friendlyiface']);
487
					
488
						if (($int <> "") && is_ipaddr($gatewayip)) {
489
							$groupmember = array();
490
							$groupmember['int']  = $int;
491
							$groupmember['gwip']  = $gatewayip;
492
							$groupmember['weight']  = isset($gateway['weight']) ? $gateway['weight'] : 1;
493
							$gateway_groups_array[$group['name']][] = $groupmember;
494
						}
495
					}
496
				}
497
				/* we should have the 1st available tier now, exit stage left */
498
				break;
499
			}
500
		}
501
	}
502
	return ($gateway_groups_array);
503
}
504

    
505
/* Update DHCP WAN Interface ip address in gateway group item */
506
function dhclient_update_gateway_groups_defaultroute($interface = "wan") {
507
	global $config, $g;
508
	foreach($config['gateways']['gateway_item'] as & $gw) {	
509
		if($gw['interface'] == $interface) {
510
			$current_gw = get_interface_gateway($interface);
511
			if($gw['gateway'] <> $current_gw) {
512
				$gw['gateway'] = $current_gw;
513
				$changed = true;
514
			}
515
		}
516
	}
517
	if($changed && $current_gw)
518
		write_config(sprintf(gettext('Updating gateway group gateway for %1$s - new gateway is %2$s'), $interfac, $current_gw));
519
}
520

    
521
function lookup_gateway_ip_by_name($name) {
522

    
523
	$gateways_arr = return_gateways_array();
524
        foreach ($gateways_arr as $gname => $gw) {
525
                if ($gw['name'] == $name || $gname == $name)
526
                        return $gw['gateway'];
527
        }
528

    
529
	return false;
530
}
531

    
532
function lookup_gateway_monitor_ip_by_name($name) {
533

    
534
        $gateways_arr = return_gateways_array();
535
	if (!empty($gateways_arr[$name])) {
536
		$gateway = $gateways_arr[$name];
537
		if(!is_ipaddr($gateway['monitor']))
538
			return $gateway['gateway'];
539

    
540
		return $gateway['monitor'];
541
        }
542

    
543
        return (false);
544
}
545

    
546
function lookup_gateway_interface_by_name($name) {
547

    
548
        $gateways_arr = return_gateways_array();
549
	if (!empty($gateways_arr[$name])) {
550
		$interfacegw = $gateway['interface'];
551
		return ($interfacegw);
552
        }
553

    
554
        return (false);
555
}
556

    
557
function get_interface_gateway($interface, &$dynamic = false) {
558
	global $config, $g;
559

    
560
	$gw = NULL;
561

    
562
	$gwcfg = $config['interfaces'][$interface];
563
	if (!empty($gwcfg['gateway']) && is_array($config['gateways']['gateway_item'])) {
564
		foreach($config['gateways']['gateway_item'] as $gateway) {
565
			if(($gateway['name'] == $gwcfg['gateway']) && (is_ipaddrv4($gateway['gateway']))) {
566
				$gw = $gateway['gateway'];
567
				break;
568
			}
569
		}
570
	}
571

    
572
	// for dynamic interfaces we handle them through the $interface_router file.
573
	if (!is_ipaddr($gw) && !is_ipaddr($gwcfg['ipaddr'])) {
574
		$realif = get_real_interface($interface);
575
		if (file_exists("{$g['tmp_path']}/{$realif}_router")) {
576
				$gw = trim(file_get_contents("{$g['tmp_path']}/{$realif}_router"), " \n");
577
			$dynamic = true;
578
		}
579
		if (file_exists("{$g['tmp_path']}/{$realif}_defaultgw"))
580
			$dynamic = "default";
581
			
582
	}
583

    
584
	/* return gateway */
585
	return ($gw);
586
}
587

    
588
function get_interface_gateway_v6($interface, &$dynamic = false) {
589
	global $config, $g;
590

    
591
	$gw = NULL;
592
	$gwcfg = $config['interfaces'][$interface];
593
	if (!empty($gwcfg['gatewayv6']) && is_array($config['gateways']['gateway_item'])) {
594
		foreach($config['gateways']['gateway_item'] as $gateway) {
595
			if(($gateway['name'] == $gwcfg['gatewayv6']) && (is_ipaddrv6($gateway['gateway']))) {
596
				$gw = $gateway['gateway'];
597
				break;
598
			}
599
		}
600
	}
601

    
602
	// for dynamic interfaces we handle them through the $interface_router file.
603
	if (!is_ipaddrv6($gw) && !is_ipaddr($gwcfg['ipaddrv6'])) {
604
			$realif = get_real_interface($interface);
605
			if (file_exists("{$g['tmp_path']}/{$realif}_routerv6")) {
606
				$gw = trim(file_get_contents("{$g['tmp_path']}/{$realif}_routerv6"), " \n");
607
				$dynamic = true;
608
			}
609
			if (file_exists("{$g['tmp_path']}/{$realif}_defaultgwv6"))
610
				$dynamic = "default";
611
			
612
	}
613
	/* return gateway */
614
	return ($gw);
615
}
616

    
617
?>
(24-24/61)