| #!/bin/bash |
| |
| # TODO: Remove this once mctp-controller-init-v2 is enabled on a platform. |
| |
| # Redirect all stdout and stderr to systemd-cat, which logs to journalctl. |
| # We can filter the messages with `journalctl -f -t usb_mctp_init` |
| exec > >(systemd-cat -t "usb_mctp_init") 2>&1 |
| |
| echo "Device found at (DEVPATH): ${DEVPATH}" |
| |
| EID_OFFSET=100 |
| EID_END=254 |
| |
| # The EID for the USB-MCTP interface. |
| # This value is an input from the udev rule. |
| LOCAL_EID=$1 |
| |
| # if the provided LOCAL_EID is missing or invalid, generate a EID |
| if [ -z "${LOCAL_EID}" ] || ! [[ "${LOCAL_EID}" =~ ^[0-9]+$ ]] || \ |
| [ "${LOCAL_EID}" -lt ${EID_OFFSET} ] || [ "${LOCAL_EID}" -gt ${EID_END} ]; then |
| |
| if [ -z "${LOCAL_EID}" ]; then |
| echo "Missing EID input parameter. Generating a random EID." >&2 |
| else |
| echo "Invalid EID: '${LOCAL_EID}'. Must be an integer between" \ |
| "'${EID_OFFSET}' and '${EID_END}'. Generating a random EID." >&2 |
| fi |
| |
| # |
| # Generate a unique ID for the local interface. This method could lead to |
| # overlapping values. A better way to do this would be to track both |
| # ADD/REMOVE events and keep track of a list of used EIDs and assign an new |
| # EID. But this requires a extra config and file read locking. For now this |
| # is the simplest way. |
| # |
| # We should always try to pass a valid EID from a platform specific config. |
| # |
| HASH_HEX=$(echo -n "${DEVPATH}" | md5sum | cut -d ' ' -f 1) |
| HASH_HEX_SHORT=$(echo -n "${HASH_HEX}" | cut -c 1-8) |
| HASH_DEC=$(( 0x${HASH_HEX_SHORT} )) |
| RANGE_SIZE=$(( ${EID_END} - ${EID_OFFSET} )) |
| LOCAL_EID=$(( (${HASH_DEC} % ${RANGE_SIZE}) + ${EID_OFFSET} )) |
| fi |
| |
| echo " Using LOCAL_EID: ${LOCAL_EID}" |
| |
| # Function to get the interface name. |
| # Returns the interface name if found, otherwise an empty string. |
| get_iface_name() { |
| local sysfs_net_path=$1 |
| local iface_name="" |
| |
| if [ -d "${sysfs_net_path}" ]; then |
| # Find the first directory inside the 'net' path. |
| # This loop is a safe way to get the name. |
| for iface_path in "${sysfs_net_path}"/*; |
| do |
| if [ -e "${iface_path}" ]; then |
| # The interface name is the directory's basename |
| iface_name=$(basename "${iface_path}") |
| break # Exit loop after finding the first interface |
| fi |
| done |
| fi |
| echo "${iface_name}" |
| } |
| |
| # The full sysfs path to the USB interface's 'net' subdirectory |
| SYSFS_NET_PATH="/sys${DEVPATH}/net" |
| |
| IFACE_NAME=$(get_iface_name "${SYSFS_NET_PATH}") |
| |
| if [ -z "${IFACE_NAME}" ]; then |
| echo "No network interface found. Directory '${SYSFS_NET_PATH}'" \ |
| "does not exist." >&2 |
| exit 4 |
| fi |
| |
| echo "Successfully found network interface: ${IFACE_NAME}" |
| |
| mctp link set "${IFACE_NAME}" up |
| mctp addr add "${LOCAL_EID}" dev "${IFACE_NAME}" |