lldpd: fix reload bug: advertisements shall default to on
[openwrt/openwrt.git] / package / network / services / lldpd / files / lldpd.init
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2008-2015 OpenWrt.org
3 # shellcheck disable=1091,2034,3037,3043,3045
4
5 START=90
6 STOP=01
7
8 CONFIG_LLDPD_WITH_CDP=y
9 CONFIG_LLDPD_WITH_EDP=y
10 CONFIG_LLDPD_WITH_FDP=y
11 CONFIG_LLDPD_WITH_LLDPMED=y
12 CONFIG_LLDPD_WITH_SNMP=y
13 CONFIG_LLDPD_WITH_SONMP=y
14
15 USE_PROCD=1
16 LLDPDBIN=/usr/sbin/lldpd
17 LLDPCLI=/usr/sbin/lldpcli
18 LLDPSOCKET=/var/run/lldpd.socket
19 LLDPD_CONF=/tmp/lldpd.conf
20 LLDPD_CONFS_DIR=/tmp/lldpd.d
21
22 LLDPD_RUN=/var/run/lldpd
23 LLDPD_RESTART_HASH=${LLDPD_RUN}/lldpd.restart_hash
24
25 . "$IPKG_INSTROOT/lib/functions/network.sh"
26
27 find_release_info()
28 {
29 [ -s /etc/os-release ] && . /etc/os-release
30 [ -z "$PRETTY_NAME" ] && [ -s /etc/openwrt_version ] && \
31 PRETTY_NAME="$(cat /etc/openwrt_version)"
32
33 echo "${PRETTY_NAME:-Unknown OpenWrt release} @ $(cat /proc/sys/kernel/hostname)"
34 }
35
36 get_config_restart_hash() {
37 local var="$1"
38 local _string _hash v
39
40 config_load 'lldpd'
41
42 config_get v 'config' 'lldp_class'; append _string "$v" ","
43 if [ "$CONFIG_LLDPD_WITH_SNMP" = "y" ]; then
44 config_get v 'config' 'agentxsocket'; append _string "$v" ","
45 fi
46 config_get v 'config' 'cid_interface'; append _string "$v" ","
47 config_get v 'config' 'filter'; append _string "$v" ","
48 config_get_bool v 'config' 'readonly_mode'; append _string "$v" ","
49 config_get_bool v 'config' 'lldp_no_version'; append _string "$v" ","
50 if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
51 config_get_bool v 'config' 'lldpmed_no_inventory'; append _string "$v" ","
52 fi
53 config_get_bool v 'config' 'enable_lldp' 1; append _string "$v" ","
54 config_get_bool v 'config' 'force_lldp'; append _string "$v" ","
55 if [ "$CONFIG_LLDPD_WITH_CDP" = "y" ]; then
56 config_get_bool v 'config' 'enable_cdp'; append _string "$v" ","
57 config_get v 'config' 'cdp_version'; append _string "$v" ","
58 config_get_bool v 'config' 'force_cdp'; append _string "$v" ","
59 config_get_bool v 'config' 'force_cdpv2'; append _string "$v" ","
60 fi
61 if [ "$CONFIG_LLDPD_WITH_EDP" = "y" ]; then
62 config_get_bool v 'config' 'enable_edp'; append _string "$v" ","
63 config_get_bool v 'config' 'force_edp'; append _string "$v" ","
64 fi
65 if [ "$CONFIG_LLDPD_WITH_FDP" = "y" ]; then
66 config_get_bool v 'config' 'enable_fdp'; append _string "$v" ","
67 config_get_bool v 'config' 'force_fdp'; append _string "$v" ","
68 fi
69 if [ "$CONFIG_LLDPD_WITH_SONMP" = "y" ]; then
70 config_get_bool v 'config' 'enable_sonmp'; append _string "$v" ","
71 config_get_bool v 'config' 'force_sonmp'; append _string "$v" ","
72 fi
73
74 _hash=$(echo -n "${_string}" | md5sum | awk '{ print $1 }')
75 export -n "$var=$_hash"
76 }
77
78 get_config_cid_ifaces() {
79 local _ifaces
80 config_get _ifaces 'config' "$2"
81
82 local _iface _ifnames=""
83 # Set noglob to prevent '*' capturing diverse file names in the for ... in
84 set -o noglob
85 for _iface in $_ifaces; do
86
87 local _l2device=""
88 if network_get_physdev _l2device "$_iface" || [ -e "/sys/class/net/$_iface" ]; then
89 append _ifnames "${_l2device:-$_iface}" ","
90 else
91 # Glob case (interface is e.g. '!eth1' or 'eth*' or '*')
92 append _ifnames "$_iface" ","
93 fi
94 done
95 # Turn noglob off i.e. enable glob again
96 set +o noglob
97
98 export -n "${1}=$_ifnames"
99 }
100
101 write_lldpd_conf()
102 {
103 local lldp_description
104
105 config_load 'lldpd'
106 config_get lldp_description 'config' 'lldp_description' "$(find_release_info)"
107
108 local lldp_hostname
109 config_get lldp_hostname 'config' 'lldp_hostname' "$(cat /proc/sys/kernel/hostname)"
110
111 local ifnames
112 get_config_cid_ifaces ifnames "interface"
113
114 local lldp_mgmt_ip
115 config_get lldp_mgmt_ip 'config' 'lldp_mgmt_ip'
116
117 # Configurable capabilities in lldpd >= v1.0.15: defaults to 'unconfigured' i.e. kernel info
118 local lldp_syscapabilities
119 config_get lldp_syscapabilities 'config' 'lldp_syscapabilities'
120
121 # Configurable capabilities in lldpd >= v1.0.15: defaults to on in lldpd
122 local lldp_capability_advertisements
123 config_get_bool lldp_capability_advertisements 'config' 'lldp_capability_advertisements' 1
124
125 # Broadcast management address in lldpd >= 0.7.15: defaults to on in lldpd
126 local lldp_mgmt_addr_advertisements
127 config_get_bool lldp_mgmt_addr_advertisements 'config' 'lldp_mgmt_addr_advertisements' 1
128
129 if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
130 local lldpmed_fast_start
131 config_get_bool lldpmed_fast_start 'config' 'lldpmed_fast_start' 0
132
133 local lldpmed_fast_start_tx_interval
134 config_get lldpmed_fast_start_tx_interval 'config' 'lldpmed_fast_start_tx_interval' 0
135
136 local lldp_location
137 config_get lldp_location 'config' 'lldp_location'
138
139 local lldp_class
140 config_get lldp_class 'config' 'lldp_class'
141
142 local lldp_policy
143 config_get lldp_policy 'config' 'lldp_policy'
144
145 fi
146
147 local lldp_agenttype
148 config_get lldp_agenttype 'config' 'lldp_agenttype' 'nearest-bridge'
149
150 local lldp_portidsubtype
151 config_get lldp_portidsubtype 'config' 'lldp_portidsubtype' 'macaddress'
152
153 local lldp_platform
154 config_get lldp_platform 'config' 'lldp_platform' ""
155
156 local lldp_tx_interval
157 config_get lldp_tx_interval 'config' 'lldp_tx_interval' 0
158
159 local lldp_tx_hold
160 config_get lldp_tx_hold 'config' 'lldp_tx_hold' 0
161
162 # Clear out the config file first
163 echo -n > "$LLDPD_CONF"
164 [ -n "$ifnames" ] && echo "configure system interface pattern $ifnames" >> "$LLDPD_CONF"
165 [ -n "$lldp_description" ] && echo "configure system description" "\"$lldp_description\"" >> "$LLDPD_CONF"
166 [ -n "$lldp_hostname" ] && echo "configure system hostname" "\"$lldp_hostname\"" >> "$LLDPD_CONF"
167 [ -n "$lldp_mgmt_ip" ] && echo "configure system ip management pattern" "\"$lldp_mgmt_ip\"" >> "$LLDPD_CONF"
168 [ -n "$lldp_syscapabilities" ] && echo "configure system capabilities enabled $lldp_syscapabilities" >> "$LLDPD_CONF"
169
170 if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ] && [ "$lldpmed_fast_start" -gt 0 ]; then
171 if [ "$lldpmed_fast_start_tx_interval" -gt 0 ]; then
172 echo "configure med fast-start tx-interval $lldpmed_fast_start_tx_interval" >> "$LLDPD_CONF"
173 else
174 echo "configure med fast-start enable" >> "$LLDPD_CONF"
175 fi
176 fi
177 if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
178 # other 'configure med xxx' statements go here
179
180 [ -n "$lldp_location" ] && echo "configure med location" "$lldp_location" >> "$LLDPD_CONF"
181
182 # Manual states that if Class (-M) is 2 or 3, at least one network policy must be defined
183 case "$lldp_class" in
184 2 | 3 ) [ -n "$lldp_policy" ] && echo "configure med policy $lldp_policy" >> "$LLDPD_CONF"
185 ;;
186 esac
187
188 fi
189
190 [ -n "$lldp_agenttype" ] && echo "configure lldp agent-type" "\"$lldp_agenttype\"" >> "$LLDPD_CONF"
191 [ -n "$lldp_portidsubtype" ] && echo "configure lldp portidsubtype" "\"$lldp_portidsubtype\"" >> "$LLDPD_CONF"
192 [ -n "$lldp_platform" ] && echo "configure system platform" "\"$lldp_platform\"" >> "$LLDPD_CONF"
193 [ -n "$lldp_tx_interval" ] && echo "configure lldp tx-interval $lldp_tx_interval" >> "$LLDPD_CONF"
194 [ "$lldp_tx_hold" -gt 0 ] && echo "configure lldp tx-hold $lldp_tx_hold" >> "$LLDPD_CONF"
195 [ "$lldp_capability_advertisements" -gt 0 ] && echo "configure lldp capabilities-advertisements" >> "$LLDPD_CONF" ||\
196 echo "unconfigure lldp capabilities-advertisements" >> "$LLDPD_CONF"
197 [ "$lldp_mgmt_addr_advertisements" -gt 0 ] && echo "configure lldp management-addresses-advertisements" >> "$LLDPD_CONF" ||\
198 echo "unconfigure lldp management-addresses-advertisements" >> "$LLDPD_CONF"
199
200 # Since lldpd's sysconfdir is /tmp, we'll symlink /etc/lldpd.d to /tmp/$LLDPD_CONFS_DIR
201 [ -e "$LLDPD_CONFS_DIR" ] || ln -s /etc/lldpd.d "$LLDPD_CONFS_DIR"
202 }
203
204 start_service() {
205
206 local enable_lldp
207 local force_lldp
208 local enable_cdp
209 local cdp_version
210 local force_cdp
211 local force_cdpv2
212 local enable_fdp
213 local force_fdp
214 local enable_sonmp
215 local force_sonmp
216 local enable_edp
217 local force_edp
218 local lldp_class
219 local lldp_no_version
220 local lldpmed_no_inventory
221 local readonly_mode
222 local agentxsocket
223 local filter
224
225 config_load 'lldpd'
226 config_get_bool enable_lldp 'config' 'enable_lldp' 1
227 config_get_bool force_lldp 'config' 'force_lldp' 0
228 if [ "$CONFIG_LLDPD_WITH_CDP" = "y" ]; then
229 config_get_bool enable_cdp 'config' 'enable_cdp' 0
230 config_get cdp_version 'config' 'cdp_version' 'cdpv1v2'
231 config_get_bool force_cdp 'config' 'force_cdp' 0
232 config_get_bool force_cdpv2 'config' 'force_cdpv2' 0
233 fi
234 if [ "$CONFIG_LLDPD_WITH_FDP" = "y" ]; then
235 config_get_bool enable_fdp 'config' 'enable_fdp' 0
236 config_get_bool force_fdp 'config' 'force_fdp' 0
237 fi
238 if [ "$CONFIG_LLDPD_WITH_SONMP" = "y" ]; then
239 config_get_bool enable_sonmp 'config' 'enable_sonmp' 0
240 config_get_bool force_sonmp 'config' 'force_sonmp' 0
241 fi
242 if [ "$CONFIG_LLDPD_WITH_EDP" = "y" ]; then
243 config_get_bool enable_edp 'config' 'enable_edp' 0
244 config_get_bool force_edp 'config' 'force_edp' 0
245 fi
246 config_get lldp_class 'config' 'lldp_class'
247 config_get_bool lldp_no_version 'config' 'lldp_no_version' 0
248 if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
249 config_get_bool lldpmed_no_inventory 'config' 'lldpmed_no_inventory' 0
250 fi
251 config_get_bool readonly_mode 'config' 'readonly_mode' 0
252 if [ "$CONFIG_LLDPD_WITH_SNMP" = "y" ]; then
253 config_get agentxsocket 'config' 'agentxsocket'
254 fi
255 config_get filter 'config' 'filter' 15
256
257 mkdir -p ${LLDPD_RUN}
258 chown lldp:lldp ${LLDPD_RUN}
259
260 # When lldpd starts, it also loads up what we write in this config file
261 write_lldpd_conf
262
263 procd_open_instance
264 procd_set_param command ${LLDPDBIN}
265 procd_append_param command -d
266
267 if [ "$enable_lldp" -gt 0 ]; then
268 if [ "$force_lldp" -gt 0 ]; then
269 procd_append_param command '-l'
270 fi
271 else
272 # Disable LLDP
273 procd_append_param command '-ll'
274 fi
275
276 if [ "$CONFIG_LLDPD_WITH_CDP" = "y" ] && [ "$enable_cdp" -gt 0 ]; then
277 if [ "$cdp_version" = "cdpv2" ]; then
278 if [ "$force_cdp" -gt 0 ]; then
279 # CDPv1 disabled, CDPv2 forced
280 procd_append_param command '-ccccc'
281 else
282 # CDPv1 disabled, CDPv2 enabled
283 procd_append_param command '-cccc'
284 fi
285 elif [ "$cdp_version" = "cdpv1v2" ]; then
286 if [ "$force_cdp" -gt 0 ] && [ "$force_cdpv2" -gt 0 ]; then
287 # CDPv1 enabled, CDPv2 forced
288 procd_append_param command '-ccc'
289 elif [ "$force_cdp" -gt 0 ]; then
290 # CDPv1 forced, CDPv2 enabled
291 procd_append_param command '-cc'
292 else
293 # CDPv1 and CDPv2 enabled
294 procd_append_param command '-c'
295 fi
296 fi
297 fi
298
299 if [ "$CONFIG_LLDPD_WITH_FDP" = "y" ] && [ "$enable_fdp" -gt 0 ]; then
300 if [ "$force_fdp" -gt 0 ]; then
301 # FDP enabled and forced
302 procd_append_param command '-ff'
303 else
304 # FDP enabled
305 procd_append_param command '-f'
306 fi
307 fi
308
309 if [ "$CONFIG_LLDPD_WITH_SONMP" = "y" ] && [ "$enable_sonmp" -gt 0 ]; then
310 if [ "$force_sonmp" -gt 0 ]; then
311 # SONMP enabled and forced
312 procd_append_param command '-ss'
313 else
314 # SONMP enabled
315 procd_append_param command '-s'
316 fi
317 fi
318
319 if [ "$CONFIG_LLDPD_WITH_EDP" = "y" ] && [ "$enable_edp" -gt 0 ]; then
320 if [ "$force_edp" -gt 0 ]; then
321 # EDP enabled and forced
322 procd_append_param command '-ee'
323 else
324 # EDP enabled
325 procd_append_param command '-e'
326 fi
327 fi
328
329 [ "$readonly_mode" -gt 0 ] && procd_append_param command '-r'
330 [ "$lldp_no_version" -gt 0 ] && procd_append_param command '-k'
331 [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ] && [ "$lldpmed_no_inventory" -gt 0 ] && procd_append_param command '-i'
332 [ -n "$lldp_class" ] && procd_append_param command -M "$lldp_class"
333 [ "$CONFIG_LLDPD_WITH_SNMP" = "y" ] && [ -n "$agentxsocket" ] && procd_append_param command -x -X "$agentxsocket"
334 [ -n "$filter" ] && procd_append_param command -H "$filter"
335
336 # ChassisID interfaces
337 local ifnames
338 get_config_cid_ifaces ifnames "cid_interface"
339
340 [ -n "$ifnames" ] && procd_append_param command -C "$ifnames"
341
342 # Overwrite default configuration locations processed by lldpcli at start
343 procd_append_param command -O "$LLDPD_CONF"
344
345 local restart_hash
346 get_config_restart_hash restart_hash
347 echo -n "$restart_hash" > "$LLDPD_RESTART_HASH"
348
349 # set auto respawn behavior
350 procd_set_param respawn
351 procd_close_instance
352 }
353
354 service_triggers() {
355 procd_add_config_trigger "config.change" "lldpd" /etc/init.d/lldpd reload
356 }
357
358 reload_service() {
359 running || return 1
360
361 local running_hash=""
362 local config_hash=""
363
364 get_config_restart_hash config_hash
365 [ -f ${LLDPD_RESTART_HASH} ] && running_hash=$(cat "$LLDPD_RESTART_HASH")
366
367 if [ "x$running_hash" != "x$config_hash" ]; then
368 # Restart LLDPd
369 # Some parameters can't be configured at runtime
370 restart
371 return 0
372 fi
373
374 $LLDPCLI -u "$LLDPSOCKET" >/dev/null 2>&1 <<-EOF
375 pause
376 unconfigure lldp custom-tlv
377 unconfigure lldp capabilities-advertisements
378 unconfigure lldp management-addresses-advertisements
379 # unconfigures user-configured system capabilities, and instead uses the kernel information:
380 unconfigure system capabilities enabled
381 unconfigure system interface pattern
382 unconfigure system description
383 unconfigure system hostname
384 unconfigure system ip management pattern
385 unconfigure system platform
386 EOF
387 if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
388 $LLDPCLI -u "$LLDPSOCKET" >/dev/null 2>&1 <<-EOF
389 unconfigure med fast-start
390 EOF
391
392 fi
393 # Rewrite lldpd.conf
394 # If something changed it should be included by the lldpcli call
395 write_lldpd_conf
396 $LLDPCLI -u "$LLDPSOCKET" -c "$LLDPD_CONF" -c "$LLDPD_CONFS_DIR" >/dev/null 2>&1
397 # Broadcast update over the wire
398 $LLDPCLI -u "$LLDPSOCKET" >/dev/null 2>&1 <<-EOF
399 resume
400 update
401 EOF
402 return 0
403 }
404
405 stop_service() {
406 rm -rf ${LLDPD_RUN} "$LLDPSOCKET" >/dev/null 2>&1
407 }
408