mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-31 19:17:12 +00:00
708101c141
Because these capability advertisements default to on in lldpd, they became absent at reload, and not restart, due to how the reload logic works ( keep daemon running, send unconfigured and then the new config via socket ), and it was not evident unless you happened to be looking for it (e.g. via pcap or tcpdump). It was also not evident from the manpage ( have now sent patches upstream ). At reload time, the unconfigure logic disabled them unless they were explicitly enabled (compare with other settings where 'unconfigure' just resets them). Now they default to on/enabled at init time, and are explicitly 'unconfigure'd at startup if the user disables them via: lldp_mgmt_addr_advertisements=0 lldp_capability_advertisements=0 In other words: explicit is necessary to disable the advertisements. The same applies to 'configure system capabilities enabled'. Technically 'unconfigure'd is the default but now it is explicit at reload. Tested on: 23.05.3 Signed-off-by: Paul Donald <newtwen+github@gmail.com>
409 lines
13 KiB
Bash
409 lines
13 KiB
Bash
#!/bin/sh /etc/rc.common
|
|
# Copyright (C) 2008-2015 OpenWrt.org
|
|
# shellcheck disable=1091,2034,3037,3043,3045
|
|
|
|
START=90
|
|
STOP=01
|
|
|
|
CONFIG_LLDPD_WITH_CDP=y
|
|
CONFIG_LLDPD_WITH_EDP=y
|
|
CONFIG_LLDPD_WITH_FDP=y
|
|
CONFIG_LLDPD_WITH_LLDPMED=y
|
|
CONFIG_LLDPD_WITH_SNMP=y
|
|
CONFIG_LLDPD_WITH_SONMP=y
|
|
|
|
USE_PROCD=1
|
|
LLDPDBIN=/usr/sbin/lldpd
|
|
LLDPCLI=/usr/sbin/lldpcli
|
|
LLDPSOCKET=/var/run/lldpd.socket
|
|
LLDPD_CONF=/tmp/lldpd.conf
|
|
LLDPD_CONFS_DIR=/tmp/lldpd.d
|
|
|
|
LLDPD_RUN=/var/run/lldpd
|
|
LLDPD_RESTART_HASH=${LLDPD_RUN}/lldpd.restart_hash
|
|
|
|
. "$IPKG_INSTROOT/lib/functions/network.sh"
|
|
|
|
find_release_info()
|
|
{
|
|
[ -s /etc/os-release ] && . /etc/os-release
|
|
[ -z "$PRETTY_NAME" ] && [ -s /etc/openwrt_version ] && \
|
|
PRETTY_NAME="$(cat /etc/openwrt_version)"
|
|
|
|
echo "${PRETTY_NAME:-Unknown OpenWrt release} @ $(cat /proc/sys/kernel/hostname)"
|
|
}
|
|
|
|
get_config_restart_hash() {
|
|
local var="$1"
|
|
local _string _hash v
|
|
|
|
config_load 'lldpd'
|
|
|
|
config_get v 'config' 'lldp_class'; append _string "$v" ","
|
|
if [ "$CONFIG_LLDPD_WITH_SNMP" = "y" ]; then
|
|
config_get v 'config' 'agentxsocket'; append _string "$v" ","
|
|
fi
|
|
config_get v 'config' 'cid_interface'; append _string "$v" ","
|
|
config_get v 'config' 'filter'; append _string "$v" ","
|
|
config_get_bool v 'config' 'readonly_mode'; append _string "$v" ","
|
|
config_get_bool v 'config' 'lldp_no_version'; append _string "$v" ","
|
|
if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
|
|
config_get_bool v 'config' 'lldpmed_no_inventory'; append _string "$v" ","
|
|
fi
|
|
config_get_bool v 'config' 'enable_lldp' 1; append _string "$v" ","
|
|
config_get_bool v 'config' 'force_lldp'; append _string "$v" ","
|
|
if [ "$CONFIG_LLDPD_WITH_CDP" = "y" ]; then
|
|
config_get_bool v 'config' 'enable_cdp'; append _string "$v" ","
|
|
config_get v 'config' 'cdp_version'; append _string "$v" ","
|
|
config_get_bool v 'config' 'force_cdp'; append _string "$v" ","
|
|
config_get_bool v 'config' 'force_cdpv2'; append _string "$v" ","
|
|
fi
|
|
if [ "$CONFIG_LLDPD_WITH_EDP" = "y" ]; then
|
|
config_get_bool v 'config' 'enable_edp'; append _string "$v" ","
|
|
config_get_bool v 'config' 'force_edp'; append _string "$v" ","
|
|
fi
|
|
if [ "$CONFIG_LLDPD_WITH_FDP" = "y" ]; then
|
|
config_get_bool v 'config' 'enable_fdp'; append _string "$v" ","
|
|
config_get_bool v 'config' 'force_fdp'; append _string "$v" ","
|
|
fi
|
|
if [ "$CONFIG_LLDPD_WITH_SONMP" = "y" ]; then
|
|
config_get_bool v 'config' 'enable_sonmp'; append _string "$v" ","
|
|
config_get_bool v 'config' 'force_sonmp'; append _string "$v" ","
|
|
fi
|
|
|
|
_hash=$(echo -n "${_string}" | md5sum | awk '{ print $1 }')
|
|
export -n "$var=$_hash"
|
|
}
|
|
|
|
get_config_cid_ifaces() {
|
|
local _ifaces
|
|
config_get _ifaces 'config' "$2"
|
|
|
|
local _iface _ifnames=""
|
|
# Set noglob to prevent '*' capturing diverse file names in the for ... in
|
|
set -o noglob
|
|
for _iface in $_ifaces; do
|
|
|
|
local _l2device=""
|
|
if network_get_physdev _l2device "$_iface" || [ -e "/sys/class/net/$_iface" ]; then
|
|
append _ifnames "${_l2device:-$_iface}" ","
|
|
else
|
|
# Glob case (interface is e.g. '!eth1' or 'eth*' or '*')
|
|
append _ifnames "$_iface" ","
|
|
fi
|
|
done
|
|
# Turn noglob off i.e. enable glob again
|
|
set +o noglob
|
|
|
|
export -n "${1}=$_ifnames"
|
|
}
|
|
|
|
write_lldpd_conf()
|
|
{
|
|
local lldp_description
|
|
|
|
config_load 'lldpd'
|
|
config_get lldp_description 'config' 'lldp_description' "$(find_release_info)"
|
|
|
|
local lldp_hostname
|
|
config_get lldp_hostname 'config' 'lldp_hostname' "$(cat /proc/sys/kernel/hostname)"
|
|
|
|
local ifnames
|
|
get_config_cid_ifaces ifnames "interface"
|
|
|
|
local lldp_mgmt_ip
|
|
config_get lldp_mgmt_ip 'config' 'lldp_mgmt_ip'
|
|
|
|
# Configurable capabilities in lldpd >= v1.0.15: defaults to 'unconfigured' i.e. kernel info
|
|
local lldp_syscapabilities
|
|
config_get lldp_syscapabilities 'config' 'lldp_syscapabilities'
|
|
|
|
# Configurable capabilities in lldpd >= v1.0.15: defaults to on in lldpd
|
|
local lldp_capability_advertisements
|
|
config_get_bool lldp_capability_advertisements 'config' 'lldp_capability_advertisements' 1
|
|
|
|
# Broadcast management address in lldpd >= 0.7.15: defaults to on in lldpd
|
|
local lldp_mgmt_addr_advertisements
|
|
config_get_bool lldp_mgmt_addr_advertisements 'config' 'lldp_mgmt_addr_advertisements' 1
|
|
|
|
if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
|
|
local lldpmed_fast_start
|
|
config_get_bool lldpmed_fast_start 'config' 'lldpmed_fast_start' 0
|
|
|
|
local lldpmed_fast_start_tx_interval
|
|
config_get lldpmed_fast_start_tx_interval 'config' 'lldpmed_fast_start_tx_interval' 0
|
|
|
|
local lldp_location
|
|
config_get lldp_location 'config' 'lldp_location'
|
|
|
|
local lldp_class
|
|
config_get lldp_class 'config' 'lldp_class'
|
|
|
|
local lldp_policy
|
|
config_get lldp_policy 'config' 'lldp_policy'
|
|
|
|
fi
|
|
|
|
local lldp_agenttype
|
|
config_get lldp_agenttype 'config' 'lldp_agenttype' 'nearest-bridge'
|
|
|
|
local lldp_portidsubtype
|
|
config_get lldp_portidsubtype 'config' 'lldp_portidsubtype' 'macaddress'
|
|
|
|
local lldp_platform
|
|
config_get lldp_platform 'config' 'lldp_platform' ""
|
|
|
|
local lldp_tx_interval
|
|
config_get lldp_tx_interval 'config' 'lldp_tx_interval' 0
|
|
|
|
local lldp_tx_hold
|
|
config_get lldp_tx_hold 'config' 'lldp_tx_hold' 0
|
|
|
|
# Clear out the config file first
|
|
echo -n > "$LLDPD_CONF"
|
|
[ -n "$ifnames" ] && echo "configure system interface pattern $ifnames" >> "$LLDPD_CONF"
|
|
[ -n "$lldp_description" ] && echo "configure system description" "\"$lldp_description\"" >> "$LLDPD_CONF"
|
|
[ -n "$lldp_hostname" ] && echo "configure system hostname" "\"$lldp_hostname\"" >> "$LLDPD_CONF"
|
|
[ -n "$lldp_mgmt_ip" ] && echo "configure system ip management pattern" "\"$lldp_mgmt_ip\"" >> "$LLDPD_CONF"
|
|
[ -n "$lldp_syscapabilities" ] && echo "configure system capabilities enabled $lldp_syscapabilities" >> "$LLDPD_CONF"
|
|
|
|
if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ] && [ "$lldpmed_fast_start" -gt 0 ]; then
|
|
if [ "$lldpmed_fast_start_tx_interval" -gt 0 ]; then
|
|
echo "configure med fast-start tx-interval $lldpmed_fast_start_tx_interval" >> "$LLDPD_CONF"
|
|
else
|
|
echo "configure med fast-start enable" >> "$LLDPD_CONF"
|
|
fi
|
|
fi
|
|
if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
|
|
# other 'configure med xxx' statements go here
|
|
|
|
[ -n "$lldp_location" ] && echo "configure med location" "$lldp_location" >> "$LLDPD_CONF"
|
|
|
|
# Manual states that if Class (-M) is 2 or 3, at least one network policy must be defined
|
|
case "$lldp_class" in
|
|
2 | 3 ) [ -n "$lldp_policy" ] && echo "configure med policy $lldp_policy" >> "$LLDPD_CONF"
|
|
;;
|
|
esac
|
|
|
|
fi
|
|
|
|
[ -n "$lldp_agenttype" ] && echo "configure lldp agent-type" "\"$lldp_agenttype\"" >> "$LLDPD_CONF"
|
|
[ -n "$lldp_portidsubtype" ] && echo "configure lldp portidsubtype" "\"$lldp_portidsubtype\"" >> "$LLDPD_CONF"
|
|
[ -n "$lldp_platform" ] && echo "configure system platform" "\"$lldp_platform\"" >> "$LLDPD_CONF"
|
|
[ -n "$lldp_tx_interval" ] && echo "configure lldp tx-interval $lldp_tx_interval" >> "$LLDPD_CONF"
|
|
[ "$lldp_tx_hold" -gt 0 ] && echo "configure lldp tx-hold $lldp_tx_hold" >> "$LLDPD_CONF"
|
|
[ "$lldp_capability_advertisements" -gt 0 ] && echo "configure lldp capabilities-advertisements" >> "$LLDPD_CONF" ||\
|
|
echo "unconfigure lldp capabilities-advertisements" >> "$LLDPD_CONF"
|
|
[ "$lldp_mgmt_addr_advertisements" -gt 0 ] && echo "configure lldp management-addresses-advertisements" >> "$LLDPD_CONF" ||\
|
|
echo "unconfigure lldp management-addresses-advertisements" >> "$LLDPD_CONF"
|
|
|
|
# Since lldpd's sysconfdir is /tmp, we'll symlink /etc/lldpd.d to /tmp/$LLDPD_CONFS_DIR
|
|
[ -e "$LLDPD_CONFS_DIR" ] || ln -s /etc/lldpd.d "$LLDPD_CONFS_DIR"
|
|
}
|
|
|
|
start_service() {
|
|
|
|
local enable_lldp
|
|
local force_lldp
|
|
local enable_cdp
|
|
local cdp_version
|
|
local force_cdp
|
|
local force_cdpv2
|
|
local enable_fdp
|
|
local force_fdp
|
|
local enable_sonmp
|
|
local force_sonmp
|
|
local enable_edp
|
|
local force_edp
|
|
local lldp_class
|
|
local lldp_no_version
|
|
local lldpmed_no_inventory
|
|
local readonly_mode
|
|
local agentxsocket
|
|
local filter
|
|
|
|
config_load 'lldpd'
|
|
config_get_bool enable_lldp 'config' 'enable_lldp' 1
|
|
config_get_bool force_lldp 'config' 'force_lldp' 0
|
|
if [ "$CONFIG_LLDPD_WITH_CDP" = "y" ]; then
|
|
config_get_bool enable_cdp 'config' 'enable_cdp' 0
|
|
config_get cdp_version 'config' 'cdp_version' 'cdpv1v2'
|
|
config_get_bool force_cdp 'config' 'force_cdp' 0
|
|
config_get_bool force_cdpv2 'config' 'force_cdpv2' 0
|
|
fi
|
|
if [ "$CONFIG_LLDPD_WITH_FDP" = "y" ]; then
|
|
config_get_bool enable_fdp 'config' 'enable_fdp' 0
|
|
config_get_bool force_fdp 'config' 'force_fdp' 0
|
|
fi
|
|
if [ "$CONFIG_LLDPD_WITH_SONMP" = "y" ]; then
|
|
config_get_bool enable_sonmp 'config' 'enable_sonmp' 0
|
|
config_get_bool force_sonmp 'config' 'force_sonmp' 0
|
|
fi
|
|
if [ "$CONFIG_LLDPD_WITH_EDP" = "y" ]; then
|
|
config_get_bool enable_edp 'config' 'enable_edp' 0
|
|
config_get_bool force_edp 'config' 'force_edp' 0
|
|
fi
|
|
config_get lldp_class 'config' 'lldp_class'
|
|
config_get_bool lldp_no_version 'config' 'lldp_no_version' 0
|
|
if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
|
|
config_get_bool lldpmed_no_inventory 'config' 'lldpmed_no_inventory' 0
|
|
fi
|
|
config_get_bool readonly_mode 'config' 'readonly_mode' 0
|
|
if [ "$CONFIG_LLDPD_WITH_SNMP" = "y" ]; then
|
|
config_get agentxsocket 'config' 'agentxsocket'
|
|
fi
|
|
config_get filter 'config' 'filter' 15
|
|
|
|
mkdir -p ${LLDPD_RUN}
|
|
chown lldp:lldp ${LLDPD_RUN}
|
|
|
|
# When lldpd starts, it also loads up what we write in this config file
|
|
write_lldpd_conf
|
|
|
|
procd_open_instance
|
|
procd_set_param command ${LLDPDBIN}
|
|
procd_append_param command -d
|
|
|
|
if [ "$enable_lldp" -gt 0 ]; then
|
|
if [ "$force_lldp" -gt 0 ]; then
|
|
procd_append_param command '-l'
|
|
fi
|
|
else
|
|
# Disable LLDP
|
|
procd_append_param command '-ll'
|
|
fi
|
|
|
|
if [ "$CONFIG_LLDPD_WITH_CDP" = "y" ] && [ "$enable_cdp" -gt 0 ]; then
|
|
if [ "$cdp_version" = "cdpv2" ]; then
|
|
if [ "$force_cdp" -gt 0 ]; then
|
|
# CDPv1 disabled, CDPv2 forced
|
|
procd_append_param command '-ccccc'
|
|
else
|
|
# CDPv1 disabled, CDPv2 enabled
|
|
procd_append_param command '-cccc'
|
|
fi
|
|
elif [ "$cdp_version" = "cdpv1v2" ]; then
|
|
if [ "$force_cdp" -gt 0 ] && [ "$force_cdpv2" -gt 0 ]; then
|
|
# CDPv1 enabled, CDPv2 forced
|
|
procd_append_param command '-ccc'
|
|
elif [ "$force_cdp" -gt 0 ]; then
|
|
# CDPv1 forced, CDPv2 enabled
|
|
procd_append_param command '-cc'
|
|
else
|
|
# CDPv1 and CDPv2 enabled
|
|
procd_append_param command '-c'
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "$CONFIG_LLDPD_WITH_FDP" = "y" ] && [ "$enable_fdp" -gt 0 ]; then
|
|
if [ "$force_fdp" -gt 0 ]; then
|
|
# FDP enabled and forced
|
|
procd_append_param command '-ff'
|
|
else
|
|
# FDP enabled
|
|
procd_append_param command '-f'
|
|
fi
|
|
fi
|
|
|
|
if [ "$CONFIG_LLDPD_WITH_SONMP" = "y" ] && [ "$enable_sonmp" -gt 0 ]; then
|
|
if [ "$force_sonmp" -gt 0 ]; then
|
|
# SONMP enabled and forced
|
|
procd_append_param command '-ss'
|
|
else
|
|
# SONMP enabled
|
|
procd_append_param command '-s'
|
|
fi
|
|
fi
|
|
|
|
if [ "$CONFIG_LLDPD_WITH_EDP" = "y" ] && [ "$enable_edp" -gt 0 ]; then
|
|
if [ "$force_edp" -gt 0 ]; then
|
|
# EDP enabled and forced
|
|
procd_append_param command '-ee'
|
|
else
|
|
# EDP enabled
|
|
procd_append_param command '-e'
|
|
fi
|
|
fi
|
|
|
|
[ "$readonly_mode" -gt 0 ] && procd_append_param command '-r'
|
|
[ "$lldp_no_version" -gt 0 ] && procd_append_param command '-k'
|
|
[ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ] && [ "$lldpmed_no_inventory" -gt 0 ] && procd_append_param command '-i'
|
|
[ -n "$lldp_class" ] && procd_append_param command -M "$lldp_class"
|
|
[ "$CONFIG_LLDPD_WITH_SNMP" = "y" ] && [ -n "$agentxsocket" ] && procd_append_param command -x -X "$agentxsocket"
|
|
[ -n "$filter" ] && procd_append_param command -H "$filter"
|
|
|
|
# ChassisID interfaces
|
|
local ifnames
|
|
get_config_cid_ifaces ifnames "cid_interface"
|
|
|
|
[ -n "$ifnames" ] && procd_append_param command -C "$ifnames"
|
|
|
|
# Overwrite default configuration locations processed by lldpcli at start
|
|
procd_append_param command -O "$LLDPD_CONF"
|
|
|
|
local restart_hash
|
|
get_config_restart_hash restart_hash
|
|
echo -n "$restart_hash" > "$LLDPD_RESTART_HASH"
|
|
|
|
# set auto respawn behavior
|
|
procd_set_param respawn
|
|
procd_close_instance
|
|
}
|
|
|
|
service_triggers() {
|
|
procd_add_config_trigger "config.change" "lldpd" /etc/init.d/lldpd reload
|
|
}
|
|
|
|
reload_service() {
|
|
running || return 1
|
|
|
|
local running_hash=""
|
|
local config_hash=""
|
|
|
|
get_config_restart_hash config_hash
|
|
[ -f ${LLDPD_RESTART_HASH} ] && running_hash=$(cat "$LLDPD_RESTART_HASH")
|
|
|
|
if [ "x$running_hash" != "x$config_hash" ]; then
|
|
# Restart LLDPd
|
|
# Some parameters can't be configured at runtime
|
|
restart
|
|
return 0
|
|
fi
|
|
|
|
$LLDPCLI -u "$LLDPSOCKET" >/dev/null 2>&1 <<-EOF
|
|
pause
|
|
unconfigure lldp custom-tlv
|
|
unconfigure lldp capabilities-advertisements
|
|
unconfigure lldp management-addresses-advertisements
|
|
# unconfigures user-configured system capabilities, and instead uses the kernel information:
|
|
unconfigure system capabilities enabled
|
|
unconfigure system interface pattern
|
|
unconfigure system description
|
|
unconfigure system hostname
|
|
unconfigure system ip management pattern
|
|
unconfigure system platform
|
|
EOF
|
|
if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then
|
|
$LLDPCLI -u "$LLDPSOCKET" >/dev/null 2>&1 <<-EOF
|
|
unconfigure med fast-start
|
|
EOF
|
|
|
|
fi
|
|
# Rewrite lldpd.conf
|
|
# If something changed it should be included by the lldpcli call
|
|
write_lldpd_conf
|
|
$LLDPCLI -u "$LLDPSOCKET" -c "$LLDPD_CONF" -c "$LLDPD_CONFS_DIR" >/dev/null 2>&1
|
|
# Broadcast update over the wire
|
|
$LLDPCLI -u "$LLDPSOCKET" >/dev/null 2>&1 <<-EOF
|
|
resume
|
|
update
|
|
EOF
|
|
return 0
|
|
}
|
|
|
|
stop_service() {
|
|
rm -rf ${LLDPD_RUN} "$LLDPSOCKET" >/dev/null 2>&1
|
|
}
|
|
|