Project

General

Profile

Download (6.92 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/usr/local/bin/php-cgi -f
2
<?php
3
/*
4
 * rc.linkup
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-2023 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
/* parse the configuration and include all functions used below */
26
require_once("globals.inc");
27
require_once("config.inc");
28
require_once("filter.inc");
29
require_once("shaper.inc");
30
require_once("interfaces.inc");
31

    
32
function handle_argument_group($iface, $action) {
33
	global $g, $config;
34

    
35
	if (empty(config_get_path("interfaces/{$iface}"))) {
36
		log_error("Cannot find interface configuration for {$iface}");
37
		return;
38
	}
39

    
40
	if (!config_path_enabled("interfaces/{$iface}")) {
41
		log_error("Linkup detected on disabled interface...Ignoring");
42
		return;
43
	}
44

    
45
	$ipaddr = config_get_path("interfaces/{$iface}/ipaddr", '');
46
	$ip6addr = config_get_path("interfaces/{$iface}/ipaddrv6", '');
47

    
48
	$staticv4 = empty($ipaddr) ? true : is_ipaddrv4($ipaddr);
49
	$staticv6 = empty($ip6addr) ? true : is_ipaddrv6($ip6addr);
50

    
51
	/* Take care of events on bridge members when IP is configured on bridge */
52
	$bridge_if = link_interface_to_bridge($iface);
53
	if (!empty($bridge_if) && empty($ipaddr) && empty($ip6addr)) {
54
		log_error("Ignoring link event for bridge member without IP address configuration");
55
		return;
56
	}
57

    
58
	/* Ignore events on LAGG members without IP address configuration */
59
	$lagg_if = link_interface_to_lagg($iface);
60
	if (!empty($lagg_if) && empty($ipaddr) && empty($ip6addr)) {
61
		log_error("Ignoring link event for LAGG member without IP address configuration");
62
		return;
63
	}
64

    
65
	$friendly = convert_friendly_interface_to_friendly_descr($iface);
66
	$addrs = [];
67
	if (!empty($ipaddr)) {
68
		$addrs[] = "4: {$ipaddr}";
69
	}
70
	if (!empty($ip6addr)) {
71
		$addrs[] = "6: {$ip6addr}";
72
	}
73
	$addrs = implode(', ', $addrs);
74
	if (($staticv4 === true) && ($staticv6 === true)) {
75
		log_error("Hotplug event detected for {$friendly}({$iface}) static IP address ({$addrs})");
76
		interfaces_staticarp_configure($iface);
77
		switch ($action) {
78
			case "stop":
79
				log_error("DEVD Ethernet detached event for {$iface}");
80
				/* Restart unbound on interface down (static),
81
				 * only when this interface is referenced in resolver configuration.
82
				 * https://redmine.pfsense.org/issues/13254
83
				 */
84
				if (config_path_enabled('unbound')) {
85
					services_unbound_configure(true, $iface);
86
				}
87
				break;
88
			case 'start':
89
				log_error("DEVD Ethernet attached event for {$iface}");
90
				$realif = get_real_interface($iface);
91
				/* NOTE: Do not generate event for OpenVPN since the daemon does that for us. */
92
				if (substr($realif, 0, 4) != "ovpn") {
93
					log_error("HOTPLUG: Triggering address refresh on {$iface} ({$realif})");
94
					touch("{$g['tmp_path']}/{$iface}_upstart4");
95
					touch("{$g['tmp_path']}/{$iface}_upstart6");
96
					send_event("interface newip {$realif}");
97
				}
98
				break;
99
			default:
100
				/* Do nothing, invalid action */
101
		}
102
	} else {
103
		log_error("Hotplug event detected for {$friendly}({$iface}) dynamic IP address ({$addrs})");
104
		switch ($action) {
105
			case "stop":
106
				log_error("DEVD Ethernet detached event for {$iface}");
107
				interface_bring_down($iface);
108
				/* Restart unbound on interface down (dynamic),
109
				 * only when this interface is referenced in resolver configuration.
110
				 * https://redmine.pfsense.org/issues/11547
111
				 * https://redmine.pfsense.org/issues/13254
112
				 */
113
				if (config_path_enabled('unbound')) {
114
					services_unbound_configure(true, $iface);
115
				}
116
				break;
117
			case "start":
118
				log_error("DEVD Ethernet attached event for {$iface}");
119
				log_error("HOTPLUG: Configuring interface {$iface}");
120
				/* trigger services restart
121
				 * see https://redmine.pfsense.org/issues/11570 */
122
				if (!$staticv4) {
123
					touch("{$g['tmp_path']}/{$iface}_upstart4");
124
					touch("{$g['tmp_path']}/{$iface}_upstart6");
125
				}
126
				// Do not try to readd to bridge otherwise em(4) has problems
127
				interface_configure($iface, true, true);
128
				/* Make sure gw monitor is configured */
129
				if ($ip6addr == 'slaac' ||
130
				    $ip6addr == 'dhcp6') {
131
					setup_gateways_monitor();
132
				}
133
				break;
134
			default:
135
				/* Do nothing, invalid action */
136
		}
137
	}
138
}
139

    
140
if (isset($_GET['interface'])) {
141
	if (!empty($_GET['interface'])) {
142
		$realiface = $_GET['interface'];
143
	}
144
	$action = $_GET['action'];
145
} else {
146
	if ($argc < 3) {
147
		log_error("HOTPLUG event: The required number of parameters not passed!");
148
		return;
149
	}
150
	$action = $argv[1];
151
	$realiface = $argv[2];
152
}
153
$action = ltrim($action, '$');
154
$realiface = ltrim($realiface, '$');
155

    
156
if (!in_array($action, ['start', 'stop'])) {
157
		log_error("HOTPLUG event: Action parameter ($action) passed is wrong - only start/stop are allowed!");
158
		return;
159
}
160

    
161
if (platform_booting()) {
162
	if (!empty($realiface)) {
163
		$interface = convert_real_interface_to_friendly_interface_name($realiface);
164
	}
165
	if (!empty($interface) &&
166
	    (config_get_path("interfaces/{$interface}/ipaddr", '') == 'dhcp')) {
167
		if (find_dhclient_process($realiface) == 0) {
168
			/* dhclient is not running */
169
			log_error("DHCP Client not running on {$interface} ($realiface), reconfiguring dhclient.");
170
			interface_dhcp_configure($interface);
171
		}
172
	} else {
173
		log_error("Ignoring link event during boot sequence.");
174
	}
175
	return;
176
}
177

    
178
if (!empty($realiface)) {
179
	if (substr($realiface, 0, 4) == 'ovpn') {
180
		log_error("Ignoring link event for OpenVPN interface");
181
		return;
182
	}
183
	$rclinkuplock = lock("rclinkup{$realiface}", LOCK_EX);
184
	$interface = convert_real_interface_to_friendly_interface_name($realiface);
185
	if (!empty($interface)) {
186
		handle_argument_group($interface, $action);
187
	}
188
	/* Check if there is any child on this one as ppp types and trigger them */
189
	foreach(config_get_path('ppps/ppp', []) as $ppp) {
190
		if (array_get_path($ppp, 'type') == 'ppp') {
191
			continue;
192
		}
193
		foreach (explode(',', array_get_path($ppp, 'ports', '')) as $parent_if) {
194
			/* The loop here is because ppp types can have real and assigned interfaces as members */
195
			$tmpiface = get_real_interface($parent_if);
196
			if ($tmpiface != $realiface) {
197
				continue;
198
			}
199
			$tmpiface = convert_real_interface_to_friendly_interface_name(array_get_path($ppp, 'if'));
200
			if (!empty($tmpiface)) {
201
				switch ($action) {
202
					case "stop":
203
						interface_bring_down($tmpiface);
204
						break;
205
					case "start":
206
						interface_configure($tmpiface, true, true);
207
						break;
208
					default:
209
						/* Do nothing, invalid action */
210
				}
211
			}
212
		}
213
	}
214
	filter_configure();
215
	unlock($rclinkuplock);
216
}
217
?>
(54-54/85)