Project

General

Profile

Download (4.47 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/usr/local/bin/php-cgi -f
2
<?php
3
/*
4
 * rc.carpbackup
5
 *
6
 * part of pfSense (https://www.pfsense.org)
7
 * Copyright (c) 2004-2013 BSD Perimeter
8
 * Copyright (c) 2013-2016 Electric Sheep Fencing
9
 * Copyright (c) 2014-2025 Rubicon Communications, LLC (Netgate)
10
 * All rights reserved.
11
 *
12
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15
 *
16
 * http://www.apache.org/licenses/LICENSE-2.0
17
 *
18
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23
 */
24

    
25
require_once("functions.inc");
26
require_once("config.inc");
27
require_once("notices.inc");
28
require_once("openvpn.inc");
29
require_once("ipsec.inc");
30
require_once("interfaces.inc");
31

    
32
if (isset($_GET['interface'])) {
33
	$argument = $_GET['interface'];
34
} else {
35
	$argument = str_replace("\n", "", $argv[1]);
36
}
37
$argument = ltrim($argument, '$');
38
if (!strstr($argument, "@")) {
39
	log_error("CARP master event triggered from wrong source {$argument}");
40
	exit;
41
}
42

    
43
list($vhid, $iface) = explode("@", $argument);
44

    
45
$friendly = convert_real_interface_to_friendly_interface_name($iface);
46
$friendly_descr = (!empty($friendly)) ? convert_friendly_interface_to_friendly_descr($friendly) : null;
47
$vips = (!empty($friendly)) ? link_interface_to_vips($friendly, '', $vhid) : null;
48
if (!is_array($vips)) {
49
	log_error("CARP master event triggered from wrong source {$argument} - no associated VIPs");
50
	exit;
51
}
52
foreach ($vips as $vip) {
53
	$notificationmsg = sprintf('HA cluster member "(%1$s@%2$s): (%3$s)" has resumed CARP state "BACKUP" for vhid %4$s',
54
					$vip['subnet'], $iface, $friendly_descr, $vhid);
55

    
56
	notify_all_remote($notificationmsg);
57
	log_error($notificationmsg);
58
}
59
restart_ppp_interfaces_using_interfaces($vips);
60

    
61
/* Stop OpenVPN clients running on this VIP, since multiple active OpenVPN clients on a CARP cluster can be problematic. */
62
$a_groups = return_gateway_groups_array(true);
63

    
64
foreach (array('server', 'client') as $mode) {
65
	foreach (config_get_path("openvpn/openvpn-{$mode}", []) as $settings) {
66
		if (empty($settings)) {
67
			continue;
68
		}
69
		if (substr($settings['interface'], 0, 4) == '_vip') {
70
			$openvpn_vip = $settings['interface'];
71
		} else if (is_array($a_groups[$settings['interface']])) {
72
			// interface is a gateway group, check CARP VIP
73
			$vip = array_get_path($a_groups, "{$settings['interface']}/0/vip");
74
			if (substr($vip, 0, 4) == '_vip') {
75
				$openvpn_vip = $vip;
76
			}
77
		} else {
78
			// this OpenVPN instance not on a CARP VIP
79
			continue;
80
		}
81
		foreach ($vips as $vip) {
82
			if ($openvpn_vip == "_vip{$vip['uniqid']}") {
83
				log_error("Stopping OpenVPN {$mode} instance on {$friendly_descr} because of transition to CARP backup.");
84
				openvpn_restart($mode, $settings);
85
			}
86
		}
87
	}
88
}
89

    
90
foreach (config_get_path("ipsec/phase1", []) as $ph1ent) {
91
	if (empty($ph1ent)) {
92
		continue;
93
	}
94
	if ((substr($ph1ent['interface'], 0, 4) == '_vip') &&
95
	    (in_array(substr($ph1ent['interface'], 4), array_column($vips, 'uniqid')))) {
96
		log_error("Reconfiguring IPsec because of transition to CARP backup.");
97
		ipsec_configure();
98
		break;
99
	}
100
}
101

    
102
/* Reconfigure radvd when necessary */
103
$rafound = false;
104
foreach (config_get_path("dhcpdv6", []) as $dhcpv6if => $dhcpv6ifconf) {
105
	if (empty($dhcpv6ifconf)) {
106
		continue;
107
	}
108
	foreach ($vips as $vip) {
109
		if ($dhcpv6ifconf['rainterface'] == "_vip{$vip['uniqid']}") {
110
			log_error("Stopping radvd instance on {$friendly_descr} because of transition to CARP backup.");
111
			$rafound = true;
112
		}
113
	}
114
}
115
if ($rafound) {
116
	services_radvd_configure();
117
}
118

    
119
/* Reconfigure DHCP Relay when necessary */
120
if (config_path_enabled('dhcrelay') &&
121
    (config_get_path('dhcrelay/carpstatusvip') == "_vip{$vip['uniqid']}")) {
122
	log_error("Stopping DHCP Relay service because of transition to CARP backup.");
123
	services_dhcrelay_configure();
124
}
125

    
126
/* Reconfigure DHCPv6 Relay when necessary */
127
if (config_path_enabled('dhcrelay6') &&
128
    (config_get_path('dhcrelay6/carpstatusvip') == "_vip{$vip['uniqid']}")) {
129
	log_error("Stopping DHCPv6 Relay service because of transition to CARP backup.");
130
	services_dhcrelay6_configure();
131
}
132

    
133
$pluginparams = array();
134
$pluginparams['type'] = 'carp';
135
$pluginparams['event'] = 'rc.carpbackup';
136
$pluginparams['interface'] = $argument;
137
pkg_call_plugins('plugin_carp', $pluginparams);
138

    
139
?>
(24-24/84)