lldpd.init 13 KB

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