Project

General

Profile

Download (17.5 KB) Statistics
| Branch: | Tag: | Revision:
1 3ad6d3bb Bill Marquette
<?php
2
/*
3 ac24dc24 Renato Botelho
 * vslb.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 c5d81585 Renato Botelho
 * Copyright (c) 2005-2008 Bill Marquette
7 b8f91b7c Luiz Souza
 * Copyright (c) 2004-2018 Rubicon Communications, LLC (Netgate)
8 ac24dc24 Renato Botelho
 * All rights reserved.
9
 *
10 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
11
 * you may not use this file except in compliance with the License.
12
 * You may obtain a copy of the License at
13 ac24dc24 Renato Botelho
 *
14 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
15 ac24dc24 Renato Botelho
 *
16 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
17
 * distributed under the License is distributed on an "AS IS" BASIS,
18
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
 * See the License for the specific language governing permissions and
20
 * limitations under the License.
21 17623ab5 Bill Marquette
 */
22 3ad6d3bb Bill Marquette
23
/* include all configuration functions */
24
25 50d86c13 Bill Marquette
class Monitor {
26
	private $conf = array();
27
	function __construct($config) {
28
		$this->conf = $config;
29
	}
30
31
	public function p() {
32
		return "check {$this->get('proto')}";
33
	}
34
	private function get($var) {
35
		return isset($this->$var) ? $this->$var : "";
36
	}
37
	protected function config($element) {
38
		return isset($this->conf[$element]) ? $this->conf[$element] : "";
39
	}
40
}
41
42
class TCPMonitor extends Monitor {
43
	protected $proto = 'tcp';
44
}
45
46
class SSLMonitor extends Monitor {
47
	protected $proto = 'ssl';
48
}
49
50
class ICMPMonitor extends Monitor {
51
	protected $proto = 'icmp';
52
}
53
54
class HTTPMonitor extends Monitor {
55
	protected $proto = 'http';
56
	function __construct($config) {
57
		parent::__construct($config);
58
	}
59
	public function p() {
60
		$method = ($this->code() != "") ? $this->code() : $this->digest();
61
		return "check {$this->proto} {$this->path()} {$this->host()} {$method}";
62
	}
63
64
	private function path() {
65
		return $this->config('path') != "" ? "'{$this->config('path')}'" : "";
66
	}
67
68
	private function host() {
69
		return $this->config('host') != "" ? "host {$this->config('host')}" : "";
70
	}
71
72
	private function code() {
73
		return $this->config('code') != "" ? "code {$this->config('code')}" : "";
74
	}
75
76
	private function digest() {
77
		return $this->config('digest') != "" ? "digest {$this->config('digest')}" : "";
78
	}
79
}
80
81
class HTTPSMonitor extends HTTPMonitor {
82
	protected $proto = 'https';
83
}
84
85
class SendMonitor extends Monitor {
86
	private $proto = 'send';
87
	function __construct($config) {
88
		parent::__construct($config);
89
	}
90
	public function p() {
91
		return "check {$this->proto} {$this->data()} expect {$this->pattern()} {$this->ssl()}";
92
	}
93
94
95
	private function data() {
96 146a1717 jim-p
		return $this->config('send') != "" ? "\"{$this->config('send')}\"" : "\"\"";
97 50d86c13 Bill Marquette
	}
98
99
	private function pattern() {
100 146a1717 jim-p
		return $this->config('expect') != "" ? "\"{$this->config('expect')}\"" : "\"\"";
101 50d86c13 Bill Marquette
	}
102
103
	private function ssl() {
104
		return $this->config('ssl') == true ? "ssl" : "";
105
	}
106
}
107
108 0919224f Bill Marquette
function echo_lbaction($action) {
109 939b2d75 Darren Embry
	global $config;
110 79262830 Phil Davis
111 939b2d75 Darren Embry
	// Index actions by name
112
	$actions_a = array();
113 6c07db48 Phil Davis
	for ($i = 0; isset($config['load_balancer']['lbaction'][$i]); $i++) {
114 0919224f Bill Marquette
		$actions_a[$config['load_balancer']['lbaction'][$i]['name']] = $config['load_balancer']['lbaction'][$i];
115 79262830 Phil Davis
	}
116 0919224f Bill Marquette
117 939b2d75 Darren Embry
	$ret = "";
118 6c07db48 Phil Davis
	$ret .= "{$actions_a[$action]['direction']} {$actions_a[$action]['type']} {$actions_a[$action]['action']}";
119 79262830 Phil Davis
	switch ($actions_a[$action]['action']) {
120
		case 'append':
121
			$ret .= " \"{$actions_a[$action]['options']['value']}\" to \"{$actions_a[$action]['options']['akey']}\"";
122
			break;
123
		case 'change':
124
			$ret .= " \"{$actions_a[$action]['options']['akey']}\" to \"{$actions_a[$action]['options']['value']}\"";
125
			break;
126
		case 'expect':
127
			$ret .= " \"{$actions_a[$action]['options']['value']}\" from \"{$actions_a[$action]['options']['akey']}\"";
128
			break;
129
		case 'filter':
130
			$ret .= " \"{$actions_a[$action]['options']['value']}\" from \"{$actions_a[$action]['options']['akey']}\"";
131
			break;
132
		case 'hash':
133
			$ret .= " \"{$actions_a[$action]['options']['akey']}\"";
134
			break;
135
		case 'log':
136
			$ret .= " \"{$actions_a[$action]['options']['akey']}\"";
137
			break;
138 939b2d75 Darren Embry
	}
139
	return $ret;
140 0919224f Bill Marquette
}
141 50d86c13 Bill Marquette
142 d3534235 jim-p
function relayd_configure($kill_first=false) {
143 939b2d75 Darren Embry
	global $config, $g;
144
145 f57a578d Darren Embry
	// have to do this until every call to filter.inc is
146
	// require_once() instead of require().
147 91b2f623 bcyrill
	if (!function_exists('filter_expand_alias_array')) {
148 f57a578d Darren Embry
		require_once("filter.inc");
149
	}
150 f38f83cd doktornotor
	require_once("util.inc");
151 d7afd900 Darren Embry
152 939b2d75 Darren Embry
	$vs_a = $config['load_balancer']['virtual_server'];
153
	$pool_a = $config['load_balancer']['lbpool'];
154
	$protocol_a = $config['load_balancer']['lbprotocol'];
155
	$setting = $config['load_balancer']['setting'];
156
157
	$check_a = array();
158 50d86c13 Bill Marquette
159 939b2d75 Darren Embry
	foreach ((array)$config['load_balancer']['monitor_type'] as $type) {
160 79262830 Phil Davis
		switch ($type['type']) {
161
			case 'icmp':
162
				$mon = new ICMPMonitor($type['options']);
163
				break;
164
			case 'tcp':
165
				$mon = new TCPMonitor($type['options']);
166
				break;
167
			case 'http':
168
				$mon = new HTTPMonitor($type['options']);
169
				break;
170
			case 'https':
171
				$mon = new HTTPSMonitor($type['options']);
172
				break;
173
			case 'send':
174
				$mon = new SendMonitor($type['options']);
175
				break;
176 939b2d75 Darren Embry
		}
177 79262830 Phil Davis
		if ($mon) {
178 939b2d75 Darren Embry
			$check_a[$type['name']] = $mon->p();
179
		}
180
	}
181 79262830 Phil Davis
182
183 939b2d75 Darren Embry
	$fd = fopen("{$g['varetc_path']}/relayd.conf", "w");
184
	$conf .= "log updates \n";
185
186
	/* Global timeout, interval and prefork settings
187
	   if not specified by the user:
188
	   - use a 1000 ms timeout value as in pfsense 2.0.1 and above
189
	   - leave interval and prefork empty, relayd will use its default values */
190 79262830 Phil Davis
191 939b2d75 Darren Embry
	if (isset($setting['timeout']) && !empty($setting['timeout'])) {
192
		$conf .= "timeout ".$setting['timeout']." \n";
193 74b7361f jim-p
	} else {
194 939b2d75 Darren Embry
		$conf .= "timeout 1000 \n";
195
	}
196 79262830 Phil Davis
197 939b2d75 Darren Embry
	if (isset($setting['interval']) && !empty($setting['interval'])) {
198
		$conf .= "interval ".$setting['interval']." \n";
199
	}
200 79262830 Phil Davis
201 939b2d75 Darren Embry
	if (isset($setting['prefork']) && !empty($setting['prefork'])) {
202
		$conf .= "prefork ".$setting['prefork']." \n";
203
	}
204 79262830 Phil Davis
205 939b2d75 Darren Embry
	/* reindex pools by name as we loop through the pools array */
206
	$pools = array();
207
	/* Virtual server pools */
208 79262830 Phil Davis
	if (is_array($pool_a)) {
209 939b2d75 Darren Embry
		for ($i = 0; isset($pool_a[$i]); $i++) {
210 79262830 Phil Davis
			if (is_array($pool_a[$i]['servers'])) {
211 939b2d75 Darren Embry
				if (!empty($pool_a[$i]['retry'])) {
212
					$retrytext = " retry {$pool_a[$i]['retry']}";
213
				} else {
214 0917cb21 Darren Embry
					$retrytext = "";
215 939b2d75 Darren Embry
				}
216 0917cb21 Darren Embry
				$conf .= "table <{$pool_a[$i]['name']}> {\n";
217
				foreach ($pool_a[$i]['servers'] as $server) {
218
					if (is_subnetv4($server)) {
219
						foreach (subnetv4_expand($server) as $ip) {
220
							$conf .= "\t{$ip}{$retrytext}\n";
221
						}
222 79262830 Phil Davis
					} else {
223 0917cb21 Darren Embry
						$conf .= "\t{$server}{$retrytext}\n";
224
					}
225
				}
226
				$conf .= "}\n";
227 939b2d75 Darren Embry
				/* Index by name for easier fetching when we loop through the virtual servers */
228
				$pools[$pool_a[$i]['name']] = $pool_a[$i];
229
			}
230
		}
231 74b7361f jim-p
	}
232 79262830 Phil Davis
//  if (is_array($protocol_a)) {
233 b6d74873 jim-p
//    for ($i = 0; isset($protocol_a[$i]); $i++) {
234
//      $proto = "{$protocol_a[$i]['type']} protocol \"{$protocol_a[$i]['name']}\" {\n";
235 79262830 Phil Davis
//      if (is_array($protocol_a[$i]['lbaction'])) {
236
//        if ($protocol_a[$i]['lbaction'][0] == "") {
237 b6d74873 jim-p
//          continue;
238
//        }
239
//        for ($a = 0; isset($protocol_a[$i]['lbaction'][$a]); $a++) {
240
//          $proto .= "  " . echo_lbaction($protocol_a[$i]['lbaction'][$a]) . "\n";
241
//        }
242
//      }
243
//      $proto .= "}\n";
244
//      $conf .= $proto;
245
//    }
246
//  }
247
248
	$conf .= "dns protocol \"dnsproto\" {\n";
249 0917cb21 Darren Embry
	$conf .= "\t" . "tcp { nodelay, sack, socket buffer 1024, backlog 1000 }\n";
250 b6d74873 jim-p
	$conf .= "}\n";
251
252 79262830 Phil Davis
	if (is_array($vs_a)) {
253 0130b756 Warren Baker
		for ($i = 0; isset($vs_a[$i]); $i++) {
254 79262830 Phil Davis
255 01ed452e Darren Embry
			$append_port_to_name = false;
256 6e9b046e jim-p
			if (is_alias($pools[$vs_a[$i]['poolname']]['port'])) {
257
				$dest_port_array = filter_expand_alias_array($pools[$vs_a[$i]['poolname']]['port']);
258 01ed452e Darren Embry
				$append_port_to_name = true;
259 79262830 Phil Davis
			} else {
260 6e9b046e jim-p
				$dest_port_array = array($pools[$vs_a[$i]['poolname']]['port']);
261 01ed452e Darren Embry
			}
262 06d84cf3 Darren Embry
			if (is_alias($vs_a[$i]['port'])) {
263
				$src_port_array = filter_expand_alias_array($vs_a[$i]['port']);
264 01ed452e Darren Embry
				$append_port_to_name = true;
265 79262830 Phil Davis
			} else if ($vs_a[$i]['port']) {
266 06d84cf3 Darren Embry
				$src_port_array = array($vs_a[$i]['port']);
267 79262830 Phil Davis
			} else {
268 06d84cf3 Darren Embry
				$src_port_array = $dest_port_array;
269 01ed452e Darren Embry
			}
270
271
			$append_ip_to_name = false;
272 183ea34c Darren Embry
			if (is_alias($vs_a[$i]['ipaddr'])) {
273 06d84cf3 Darren Embry
				$ip_list = array();
274 183ea34c Darren Embry
				foreach (filter_expand_alias_array($vs_a[$i]['ipaddr']) as $item) {
275 06d84cf3 Darren Embry
					log_error("item is $item");
276 183ea34c Darren Embry
					if (is_subnetv4($item)) {
277
						$ip_list = array_merge($ip_list, subnetv4_expand($item));
278 79262830 Phil Davis
					} else {
279 183ea34c Darren Embry
						$ip_list[] = $item;
280
					}
281
				}
282
				$append_ip_to_name = true;
283 79262830 Phil Davis
			} else if (is_subnetv4($vs_a[$i]['ipaddr'])) {
284 0917cb21 Darren Embry
				$ip_list = subnetv4_expand($vs_a[$i]['ipaddr']);
285 01ed452e Darren Embry
				$append_ip_to_name = true;
286 79262830 Phil Davis
			} else {
287 0917cb21 Darren Embry
				$ip_list = array($vs_a[$i]['ipaddr']);
288
			}
289 01ed452e Darren Embry
290 0917cb21 Darren Embry
			for ($j = 0; $j < count($ip_list); $j += 1) {
291
				$ip = $ip_list[$j];
292 01ed452e Darren Embry
				for ($k = 0; $k < count($src_port_array) && $k < count($dest_port_array); $k += 1) {
293 6c07db48 Phil Davis
					$src_port = $src_port_array[$k];
294 01ed452e Darren Embry
					$dest_port = $dest_port_array[$k];
295 9195a837 jim-p
					if (is_portrange($dest_port)) {
296
						$dest_ports = explode(':', $dest_port);
297
						$dest_port = $dest_ports[0];
298
					}
299 01ed452e Darren Embry
300
					$name = $vs_a[$i]['name'];
301
					if ($append_ip_to_name) {
302
						$name .= "_" . $j;
303 0917cb21 Darren Embry
					}
304 01ed452e Darren Embry
					if ($append_port_to_name) {
305 9195a837 jim-p
						$name .= "_" . str_replace(":", "_", $src_port);
306 0917cb21 Darren Embry
					}
307
308 01ed452e Darren Embry
					if (($vs_a[$i]['mode'] == 'relay') || ($vs_a[$i]['relay_protocol'] == 'dns')) {
309
						$conf .= "relay \"{$name}\" {\n";
310
						$conf .= "  listen on {$ip} port {$src_port}\n";
311 0917cb21 Darren Embry
312 01ed452e Darren Embry
						if ($vs_a[$i]['relay_protocol'] == "dns") {
313
							$conf .= "  protocol \"dnsproto\"\n";
314
						} else {
315
							$conf .= "  protocol \"{$vs_a[$i]['relay_protocol']}\"\n";
316
						}
317
						$lbmode = "";
318 79262830 Phil Davis
						if ($pools[$vs_a[$i]['poolname']]['mode'] == "loadbalance") {
319 01ed452e Darren Embry
							$lbmode = "mode loadbalance";
320
						}
321 0917cb21 Darren Embry
322 6e9b046e jim-p
						$conf .= "  forward to <{$vs_a[$i]['poolname']}> port {$dest_port} {$lbmode} {$check_a[$pools[$vs_a[$i]['poolname']]['monitor']]} \n";
323 0917cb21 Darren Embry
324 6c07db48 Phil Davis
						if (isset($vs_a[$i]['sitedown']) && strlen($vs_a[$i]['sitedown']) > 0 && ($vs_a[$i]['relay_protocol'] != 'dns')) {
325 6e9b046e jim-p
							$conf .= "  forward to <{$vs_a[$i]['sitedown']}> port {$dest_port} {$lbmode} {$check_a[$pools[$vs_a[$i]['poolname']]['monitor']]} \n";
326 79262830 Phil Davis
						}
327 01ed452e Darren Embry
						$conf .= "}\n";
328 6c07db48 Phil Davis
					} else {
329 01ed452e Darren Embry
						$conf .= "redirect \"{$name}\" {\n";
330
						$conf .= "  listen on {$ip} port {$src_port}\n";
331 6e9b046e jim-p
						$conf .= "  forward to <{$vs_a[$i]['poolname']}> port {$dest_port} {$check_a[$pools[$vs_a[$i]['poolname']]['monitor']]} \n";
332 0917cb21 Darren Embry
333 79262830 Phil Davis
						if (isset($config['system']['lb_use_sticky'])) {
334 01ed452e Darren Embry
							$conf .= "  sticky-address\n";
335 79262830 Phil Davis
						}
336 01ed452e Darren Embry
337
						/* sitedown MUST use the same port as the primary pool - sucks, but it's a relayd thing */
338 79262830 Phil Davis
						if (isset($vs_a[$i]['sitedown']) && strlen($vs_a[$i]['sitedown']) > 0 && ($vs_a[$i]['relay_protocol'] != 'dns')) {
339 34bf3512 jim-p
							$conf .= "  forward to <{$vs_a[$i]['sitedown']}> port {$dest_port} {$check_a[$pools[$vs_a[$i]['sitedown']]['monitor']]} \n";
340 79262830 Phil Davis
						}
341 01ed452e Darren Embry
342
						$conf .= "}\n";
343
					}
344 b6d74873 jim-p
				}
345 0130b756 Warren Baker
			}
346
		}
347
	}
348
	fwrite($fd, $conf);
349
	fclose($fd);
350
351
	if (is_process_running('relayd')) {
352 6c07db48 Phil Davis
		if (!empty($vs_a)) {
353 d3534235 jim-p
			if ($kill_first) {
354 f38f83cd doktornotor
				sigkillbyname("relayd", "TERM");
355 108e868d jim-p
				/* Remove all active relayd anchors now that relayd is no longer running. */
356
				cleanup_lb_anchor("*");
357 d3534235 jim-p
				mwexec("/usr/local/sbin/relayd -f {$g['varetc_path']}/relayd.conf");
358
			} else {
359
				// it's running and there is a config, just reload
360
				mwexec("/usr/local/sbin/relayctl reload");
361
			}
362 0130b756 Warren Baker
		} else {
363
			/*
364
			 * XXX: Something breaks our control connection with relayd
365
			 * and makes 'relayctl stop' not work
366
			 * rule reloads are the current suspect
367
			 * mwexec('/usr/local/sbin/relayctl stop');
368
			 *  returns "command failed"
369
			 */
370 f38f83cd doktornotor
			sigkillbyname("relayd", "TERM");
371 108e868d jim-p
			/* Remove all active relayd anchors now that relayd is no longer running. */
372
			cleanup_lb_anchor("*");
373 0130b756 Warren Baker
		}
374 b1bd2119 Chris Buechler
	} else {
375 79262830 Phil Davis
		if (!empty($vs_a)) {
376 0130b756 Warren Baker
			// not running and there is a config, start it
377 108e868d jim-p
			/* Remove all active relayd anchors so it can start fresh. */
378
			cleanup_lb_anchor("*");
379 0130b756 Warren Baker
			mwexec("/usr/local/sbin/relayd -f {$g['varetc_path']}/relayd.conf");
380
		}
381 b1bd2119 Chris Buechler
	}
382 3ad6d3bb Bill Marquette
}
383
384 a776c720 jim-p
function get_lb_redirects() {
385
/*
386
# relayctl show summary
387
Id   Type      Name                      Avlblty Status
388
1    redirect  testvs2                           active
389
5    table     test2:80                          active (3 hosts up)
390
11   host      192.168.1.2               91.55%  up
391
10   host      192.168.1.3               100.00% up
392
9    host      192.168.1.4               88.73%  up
393
3    table     test:80                           active (1 hosts up)
394
7    host      192.168.1.2               66.20%  down
395
6    host      192.168.1.3               97.18%  up
396
0    redirect  testvs                            active
397
3    table     test:80                           active (1 hosts up)
398
7    host      192.168.1.2               66.20%  down
399
6    host      192.168.1.3               97.18%  up
400
4    table     testvs-sitedown:80                active (1 hosts up)
401
8    host      192.168.1.4               84.51%  up
402
# relayctl show redirects
403
Id   Type      Name                      Avlblty Status
404
1    redirect  testvs2                           active
405
0    redirect  testvs                            active
406
# relayctl show redirects
407
Id   Type      Name                      Avlblty Status
408
1    redirect  testvs2                           active
409 79262830 Phil Davis
		   total: 2 sessions
410
		   last: 2/60s 2/h 2/d sessions
411
		   average: 1/60s 0/h 0/d sessions
412 a776c720 jim-p
0    redirect  testvs                            active
413
*/
414
	$rdr_a = array();
415
	exec('/usr/local/sbin/relayctl show redirects 2>&1', $rdr_a);
416 b6d74873 jim-p
	$relay_a = array();
417
	exec('/usr/local/sbin/relayctl show relays 2>&1', $relay_a);
418 a776c720 jim-p
	$vs = array();
419 ff160984 jim-p
	$cur_entry = "";
420 a776c720 jim-p
	for ($i = 0; isset($rdr_a[$i]); $i++) {
421
		$line = $rdr_a[$i];
422
		if (preg_match("/^[0-9]+/", $line)) {
423
			$regs = array();
424 79262830 Phil Davis
			if ($x = preg_match("/^[0-9]+\s+redirect\s+([^\s]+)\s+([^\s]+)/", $line, $regs)) {
425 ff160984 jim-p
				$cur_entry = trim($regs[1]);
426 a776c720 jim-p
				$vs[trim($regs[1])] = array();
427
				$vs[trim($regs[1])]['status'] = trim($regs[2]);
428
			}
429 ff160984 jim-p
		} elseif (($x = preg_match("/^\s+total:\s(.*)\ssessions/", $line, $regs)) && !empty($cur_entry)) {
430
			$vs[$cur_entry]['total'] = trim($regs[1]);
431
		} elseif (($x = preg_match("/^\s+last:\s(.*)\ssessions/", $line, $regs)) && !empty($cur_entry)) {
432
			$vs[$cur_entry]['last'] = trim($regs[1]);
433
		} elseif (($x = preg_match("/^\s+average:(.*)\ssessions/", $line, $regs)) && !empty($cur_entry)) {
434
			$vs[$cur_entry]['average'] = trim($regs[1]);
435 a776c720 jim-p
		}
436
	}
437 ff160984 jim-p
	$cur_entry = "";
438 b6d74873 jim-p
	for ($i = 0; isset($relay_a[$i]); $i++) {
439
		$line = $relay_a[$i];
440
		if (preg_match("/^[0-9]+/", $line)) {
441
			$regs = array();
442 79262830 Phil Davis
			if ($x = preg_match("/^[0-9]+\s+relay\s+([^\s]+)\s+([^\s]+)/", $line, $regs)) {
443 ff160984 jim-p
				$cur_entry = trim($regs[1]);
444 b6d74873 jim-p
				$vs[trim($regs[1])] = array();
445
				$vs[trim($regs[1])]['status'] = trim($regs[2]);
446
			}
447 ff160984 jim-p
		} elseif (($x = preg_match("/^\s+total:\s(.*)\ssessions/", $line, $regs)) && !empty($cur_entry)) {
448
			$vs[$cur_entry]['total'] = trim($regs[1]);
449
		} elseif (($x = preg_match("/^\s+last:\s(.*)\ssessions/", $line, $regs)) && !empty($cur_entry)) {
450
			$vs[$cur_entry]['last'] = trim($regs[1]);
451
		} elseif (($x = preg_match("/^\s+average:(.*)\ssessions/", $line, $regs)) && !empty($cur_entry)) {
452
			$vs[$cur_entry]['average'] = trim($regs[1]);
453 b6d74873 jim-p
		}
454
	}
455 a776c720 jim-p
	return $vs;
456
}
457
458
function get_lb_summary() {
459
	$relayctl = array();
460
	exec('/usr/local/sbin/relayctl show summary 2>&1', $relayctl);
461
	$relay_hosts=Array();
462 79262830 Phil Davis
	foreach ((array) $relayctl as $line) {
463 cfbfd941 smos
		$t = explode("\t", $line);
464 a776c720 jim-p
		switch (trim($t[1])) {
465
			case "table":
466
				$curpool=trim($t[2]);
467 9859b2b5 Darren Embry
				break;
468 a776c720 jim-p
			case "host":
469
				$curhost=trim($t[2]);
470
				$relay_hosts[$curpool][$curhost]['avail']=trim($t[3]);
471
				$relay_hosts[$curpool][$curhost]['state']=trim($t[4]);
472 9859b2b5 Darren Embry
				break;
473 a776c720 jim-p
		}
474
	}
475
	return $relay_hosts;
476
}
477
478 108e868d jim-p
/* Get a list of all relayd virtual server anchors */
479
function get_lb_anchors() {
480
	/* NOTE: These names come back prepended with "relayd/" e.g. "relayd/MyVSName" */
481
	return explode("\n", trim(`/sbin/pfctl -sA -a relayd | /usr/bin/awk '{print $1;}'`));
482
}
483
484
/* Remove NAT rules from a relayd anchor that is no longer in use.
485
	$anchorname can either be * to clear all anchors or a specific anchor name.*/
486
function cleanup_lb_anchor($anchorname = "*") {
487
	$lbanchors = get_lb_anchors();
488
	foreach ($lbanchors as $lba) {
489 31b1f1e1 jim-p
		/* Skip empty/blank results */
490
		if (empty($lba)) {
491
			continue;
492
		}
493 108e868d jim-p
		if (($anchorname == "*") || ($lba == "relayd/{$anchorname}")) {
494
			/* Flush both the NAT and the Table for the anchor, so it will be completely removed by pf. */
495
			mwexec("/sbin/pfctl -a " . escapeshellarg($lba) . " -F nat");
496
			mwexec("/sbin/pfctl -a " . escapeshellarg($lba) . " -F Tables");
497
		}
498
	}
499
}
500
501
/* Mark an anchor for later cleanup. This will allow us to remove an old VS name */
502
function cleanup_lb_mark_anchor($name) {
503
	global $g;
504
	/* Nothing to do! */
505 79262830 Phil Davis
	if (empty($name)) {
506 108e868d jim-p
		return;
507 79262830 Phil Davis
	}
508 108e868d jim-p
	$filename = "{$g['tmp_path']}/relayd_anchors_remove";
509
	$cleanup_anchors = array();
510
	/* Read in any currently unapplied name changes */
511 79262830 Phil Davis
	if (file_exists($filename)) {
512 108e868d jim-p
		$cleanup_anchors = explode("\n", file_get_contents($filename));
513 79262830 Phil Davis
	}
514 108e868d jim-p
	/* Only add the anchor to the list if it's not already there. */
515 79262830 Phil Davis
	if (!in_array($name, $cleanup_anchors)) {
516 108e868d jim-p
		$cleanup_anchors[] = $name;
517 79262830 Phil Davis
	}
518 108e868d jim-p
	file_put_contents($filename, implode("\n", $cleanup_anchors));
519
}
520
521
/* Cleanup relayd anchors that have been marked for cleanup. */
522
function cleanup_lb_marked() {
523
	global $g, $config;
524
	$filename = "{$g['tmp_path']}/relayd_anchors_remove";
525
	$cleanup_anchors = array();
526
	/* Nothing to do! */
527
	if (!file_exists($filename)) {
528
		return;
529
	} else {
530
		$cleanup_anchors = explode("\n", file_get_contents($filename));
531
		/* Nothing to do! */
532 79262830 Phil Davis
		if (empty($cleanup_anchors)) {
533 108e868d jim-p
			return;
534 79262830 Phil Davis
		}
535 108e868d jim-p
	}
536
537
	/* Load current names so we can make sure we don't remove an anchor that is still in use. */
538
	$vs_a = $config['load_balancer']['virtual_server'];
539
	$active_vsnames = array();
540 79262830 Phil Davis
	if (is_array($vs_a)) {
541 108e868d jim-p
		foreach ($vs_a as $vs) {
542
			$active_vsnames[] = $vs['name'];
543
		}
544
	}
545
546
	foreach ($cleanup_anchors as $anchor) {
547
		/* Only cleanup an anchor if it is not still active. */
548
		if (!in_array($anchor, $active_vsnames)) {
549
			cleanup_lb_anchor($anchor);
550
		}
551
	}
552
	unlink_if_exists($filename);
553
}
554
555 9b0ddd8c Ermal
?>