]>
Commit | Line | Data |
---|---|---|
e9ea243e MT |
1 | #!/bin/bash |
2 | ||
3 | . /usr/lib/network/functions | |
4 | ||
5 | # Configure logging | |
6 | LOG_FACILITY="dhclient-script" | |
7 | ||
9038a844 MT |
8 | network_settings_read |
9 | ||
e9ea243e MT |
10 | assert isset interface |
11 | assert isset reason | |
12 | ||
13 | assert device_exists ${interface} | |
14 | ||
e9ea243e MT |
15 | basename="$(basename $0)" |
16 | log DEBUG "${basename} called for interface=${interface} reason=${reason}" | |
17 | ||
83d72e63 MT |
18 | # Log all information from dhclient |
19 | if enabled DEBUG; then | |
20 | while read line; do | |
21 | [[ ${line} =~ ^(cur|old|new)_ ]] || continue | |
22 | log DEBUG " ${line}" | |
23 | done <<< "$(printenv | sort)" | |
24 | fi | |
25 | ||
e9ea243e MT |
26 | # Main pitchfork. |
27 | case "${reason}" in | |
28 | MEDIUM) | |
29 | # Linux does not handle MEDIUM. | |
30 | exit 0 | |
31 | ;; | |
32 | ||
83d72e63 MT |
33 | # IPv6 |
34 | ||
35 | PREINIT6) | |
36 | if ! device_is_up "${interface}"; then | |
37 | log WARNING "Device '${interface}' was not brought up before starting the DHCP client" | |
38 | device_set_up "${interface}" | |
39 | fi | |
40 | ||
41 | # Flush all other aborted IP addresses | |
42 | ipv6_address_flush "${interface}" | |
43 | ||
44 | # Wait until DAD for the link-local address has finished | |
45 | for address in $(ipv6_device_get_addresses "${interface}" --scope="link"); do | |
46 | ipv6_wait_for_dad "${address}" "${interface}" && exit ${EXIT_OK} | |
47 | done | |
48 | ||
49 | log ERROR "There is no active link-local address on ${interface}" | |
50 | ||
51 | exit ${EXIT_ERROR} | |
52 | ;; | |
53 | ||
54 | BOUND6) | |
55 | # We will be called twice. Once for the assigned address and once for an assigned prefix. | |
56 | ||
57 | # Handle temporarily-assigned address | |
58 | if isset new_ip6_address && isset new_ip6_prefixlen; then | |
59 | ipv6_address_add "${new_ip6_address}/${new_ip6_prefixlen}" "${interface}" \ | |
60 | --valid-lifetime="${new_max_life}" --preferred-lifetime="${new_preferred_life}" | |
61 | ||
62 | # Save configuration | |
c041b631 MT |
63 | db_set "${interface}/ipv6/local-ip-address" "${new_ip6_address}/${new_ip6_prefixlen}" |
64 | db_set "${interface}/ipv6/active" 1 | |
65 | #db_set "${interface}/ipv6/domain-name" "${new_ | |
83d72e63 MT |
66 | |
67 | exit 0 | |
68 | ||
69 | # Handle Prefix Delegation | |
70 | elif isset new_ip6_prefix; then | |
c041b631 | 71 | db_set "${interface}/ipv6/delegated-prefix" "${new_ip6_prefix}" |
83d72e63 MT |
72 | |
73 | exit 0 | |
74 | fi | |
75 | ;; | |
76 | ||
77 | RENEW6|REBIND6) | |
78 | # Will be called twice like BOUND6. | |
79 | ||
80 | if isset new_ip6_address && isset new_ip6_prefixlen; then | |
81 | # Update nameservers if those have changed | |
82 | if [[ "${old_dhcp6_name_servers}" != "${new_dhcp6_name_servers}" ]]; then | |
c041b631 | 83 | db_set "${interface}/ipv6/domain-name-servers" "${new_dhcp6_name_servers}" |
83d72e63 MT |
84 | dns_generate_resolvconf |
85 | fi | |
86 | ||
87 | # Update the lifetime if the address has not changed | |
88 | if [[ "${old_ip6_address}" = "${new_ip6_address}" ]]; then | |
89 | ipv6_address_change_lifetime "${new_ip6_address}/${new_ip6_prefixlen}" "${interface}" \ | |
90 | --valid-lifetime="${new_max_life}" --preferred-lifetime="${new_preferred_life}" | |
91 | ||
92 | exit ${EXIT_OK} | |
93 | fi | |
94 | ||
95 | # Remove any old IP addresses | |
96 | if [ -n "${old_ip6_address}" ]; then | |
97 | ipv6_address_del "${old_ip6_address}/${old_ip6_prefixlen}" "${interface}" | |
98 | fi | |
99 | ||
c041b631 MT |
100 | # Update the database |
101 | db_set "${interface}/ipv6/local-ip-address" \ | |
102 | "${new_ip6_address}/${new_ip6_prefixlen}" | |
103 | ||
83d72e63 MT |
104 | # Add the new one |
105 | ipv6_address_add "${new_ip6_address}/${new_ip6_prefixlen}" "${interface}" \ | |
106 | --valid-lifetime="${new_max_life}" --preferred-lifetime="${new_preferred_life}" | |
107 | ||
108 | exit ${EXIT_OK} | |
109 | ||
110 | # Handle Prefix Delegation | |
111 | elif isset new_ip6_prefix || isset old_ip6_prefix; then | |
112 | if [[ "${old_ip6_prefix}" = "${new_ip6_prefix}" ]]; then | |
113 | # TODO What do we need to do if the prefix hasn't changed? | |
114 | exit ${EXIT_OK} | |
115 | fi | |
116 | ||
117 | log DEBUG "The delegated prefix has changed from ${old_ip6_prefix} to ${new_ip6_prefix}" | |
c041b631 | 118 | db_set "${interface}/ipv6/delegated-prefix" "${new_ip6_prefix}" |
83d72e63 MT |
119 | |
120 | exit ${EXIT_OK} | |
121 | fi | |
122 | ;; | |
123 | ||
124 | DEPREF6) | |
125 | # Check if all necessary information is there | |
126 | if ! isset cur_ip6_address || ! isset cur_ip6_prefixlen; then | |
127 | exit ${EXIT_ERROR} | |
128 | fi | |
129 | ||
130 | # Set lifetime to zero | |
131 | ipv6_address_change_lifetime "${cur_ip6_address}/${cur_ip6_prefixlen}" "${interface}" \ | |
132 | --preferred-lifetime=0 || exit ${EXIT_ERROR} | |
133 | ;; | |
134 | ||
135 | # IPv4 | |
136 | ||
e9ea243e MT |
137 | PREINIT) |
138 | # Bring up the device if it hasn't been done before. | |
139 | if ! device_is_up ${interface}; then | |
140 | log DEBUG "The interface '${interface}' does not appear to be up." | |
141 | ||
142 | zone_up ${interface} | |
143 | fi | |
144 | ||
145 | # If the use configured a delay, we will honour that. | |
146 | if [ -n "${DELAY}" ]; then | |
147 | assert isinteger DELAY | |
148 | sleep ${DELAY} | |
149 | ||
150 | # If he didn't, we will try to detect is STP has brought the | |
151 | # bridge up. | |
152 | elif device_is_bridge ${interface}; then | |
153 | counter=60 | |
154 | ||
155 | while [ ${counter} -gt 0 ]; do | |
156 | # We may end this, when the bridge is in forwarding mode. | |
157 | if bridge_is_forwarding ${interface}; then | |
158 | log DEBUG "Bridge '${interface}' is in forwarding mode." | |
159 | break | |
160 | fi | |
161 | ||
162 | counter=$(( ${counter} - 1 )) | |
163 | sleep 1 | |
164 | done | |
165 | ||
166 | # Tell the daemon, that we are not ready to go on. | |
167 | if [ ${counter} -eq 0 ]; then | |
168 | log ERROR "Bridge '${interface}' is not in forwarding mode." | |
169 | log ERROR "Could not go on with getting a DHCP lease. Exiting." | |
170 | ||
171 | exit 1 | |
172 | fi | |
173 | fi | |
174 | ||
175 | exit 0 | |
176 | ;; | |
177 | ||
e9ea243e MT |
178 | BOUND|RENEW|REBIND|REBOOT) |
179 | # Check if the IP address has changed. If so, delete all routes and stuff. | |
180 | if [ -n "${old_ip_address}" -a "${old_ip_address}" != "${new_ip_address}" ]; then | |
181 | ipv4_flush_device ${interface} | |
182 | fi | |
183 | ||
184 | case "${reason}" in | |
185 | BOUND|REBOOT) | |
186 | if [ ! "${old_ip_address}" = "${new_ip_address}" ] || \ | |
187 | [ ! "${old_subnet_mask}" = "${new_subnet_mask}" ] || \ | |
188 | [ ! "${old_network_number}" = "${new_network_number}" ] || \ | |
189 | [ ! "${old_broadcast_address}" = "${new_broadcast_address}" ] || \ | |
190 | [ ! "${old_routers}" = "${new_routers}" ] || \ | |
191 | [ ! "${old_interface_mtu}" = "${new_interface_mtu}" ]; then | |
192 | ||
193 | ||
194 | # Calc a prefix out of address and subnet mask. | |
195 | new_prefix="$(ipv4_get_prefix ${new_ip_address} ${new_subnet_mask})" | |
196 | ||
197 | # Set the new ip address. | |
198 | ip_address_add ${interface} ${new_ip_address}/${new_prefix} | |
199 | device_set_up ${interface} | |
200 | ||
201 | ||
202 | # A MTU of 576 is used for X.25 and dialup connections. Some broken DHCP | |
203 | # servers send out an MTU of 576 bytes, which will be ignored. | |
204 | if [ -n "${new_interface_mtu}" ] && [ ${new_interface_mtu} -gt 576 ]; then | |
205 | device_set_mtu ${interface} ${new_interface_mtu} | |
206 | fi | |
207 | ||
208 | # Save configuration | |
c041b631 MT |
209 | db_set "${interface}/ipv4/type" "ipv4-dhcp" |
210 | db_set "${interface}/ipv4/local-ip-address" \ | |
211 | "${new_ip_address}/${new_prefix}" | |
212 | db_set "${interface}/ipv4/remote-ip-address" "${new_routers}" | |
213 | db_set "${interface}/ipv4/active" 1 | |
214 | db_set "${interface}/ipv4/domain-name" "${new_domain_name}" | |
215 | db_set "${interface}/ipv4/domain-name-servers" \ | |
216 | "${new_domain_name_servers}" | |
217 | db_set "${interface}/ipv4/domain-name-servers-priority" \ | |
218 | "${DNS_SERVER_DYNAMIC_PRIORITY}" | |
e9ea243e MT |
219 | |
220 | # Update the routing tables. | |
221 | routing_update ${interface} ipv4 | |
2af98498 | 222 | routing_default_update |
a9ebc53b KB |
223 | |
224 | # Update resolv.conf | |
225 | dns_generate_resolvconf | |
e9ea243e MT |
226 | fi |
227 | ;; | |
228 | esac | |
229 | ||
230 | exit 0 | |
231 | ;; | |
232 | ||
233 | EXPIRE|FAIL|RELEASE|STOP) | |
234 | # Remove the currently configured addresses from the device. | |
235 | if [ -n "${old_ip_address}" ]; then | |
236 | ipv4_flush_device ${interface} | |
237 | fi | |
238 | ||
c041b631 | 239 | db_delete "${interface}/ipv4" |
2af98498 MT |
240 | routing_default_update |
241 | ||
e9ea243e MT |
242 | exit 0 |
243 | ;; | |
83d72e63 MT |
244 | |
245 | *) | |
246 | log ERROR "Unhandled reason: ${reason}" | |
247 | ;; | |
e9ea243e MT |
248 | esac |
249 | ||
250 | exit 1 |