You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.0 KiB

#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
TARGET_ETH0_NODE="ethernet@fe010000"
TARGET_ETH1_NODE="ethernet@fe2a0000"
TEMP_NAME="tera-swap0"
log_message() {
echo "tera-ethernet-map: $*"
}
node_for_interface() {
node_path=$(readlink -f "/sys/class/net/$1/device/of_node" 2>/dev/null) || return 1
echo "${node_path##*/}"
}
wait_for_interfaces() {
attempt=0
while [ "$attempt" -lt 5 ]; do
if [ -e /sys/class/net/eth0 ] && [ -e /sys/class/net/eth1 ]; then
return 0
fi
attempt=$((attempt + 1))
sleep 1
done
return 1
}
start_mapping() {
if ! wait_for_interfaces; then
log_message "eth0/eth1 did not appear"
return 1
fi
eth0_node=$(node_for_interface eth0) || {
log_message "cannot resolve eth0 device-tree node"
return 1
}
eth1_node=$(node_for_interface eth1) || {
log_message "cannot resolve eth1 device-tree node"
return 1
}
if [ "$eth0_node" = "$TARGET_ETH0_NODE" ] && \
[ "$eth1_node" = "$TARGET_ETH1_NODE" ]; then
log_message "target mapping is already active"
return 0
fi
if [ "$eth0_node" != "$TARGET_ETH1_NODE" ] || \
[ "$eth1_node" != "$TARGET_ETH0_NODE" ]; then
log_message "unexpected mapping: eth0=$eth0_node eth1=$eth1_node"
return 1
fi
if ip link show dev "$TEMP_NAME" >/dev/null 2>&1; then
log_message "temporary interface $TEMP_NAME already exists"
return 1
fi
ip link set dev eth0 down || return 1
ip link set dev eth1 down || return 1
ip link set dev eth0 name "$TEMP_NAME" || return 1
if ! ip link set dev eth1 name eth0; then
ip link set dev "$TEMP_NAME" name eth0 >/dev/null 2>&1
log_message "failed to rename original eth1 to eth0; rolled back"
return 1
fi
if ! ip link set dev "$TEMP_NAME" name eth1; then
ip link set dev eth0 name eth1 >/dev/null 2>&1
ip link set dev "$TEMP_NAME" name eth0 >/dev/null 2>&1
log_message "failed to finish interface swap; rolled back"
return 1
fi
eth0_node=$(node_for_interface eth0)
eth1_node=$(node_for_interface eth1)
if [ "$eth0_node" != "$TARGET_ETH0_NODE" ] || \
[ "$eth1_node" != "$TARGET_ETH1_NODE" ]; then
log_message "post-swap verification failed: eth0=$eth0_node eth1=$eth1_node"
return 1
fi
log_message "mapping applied: eth0=$eth0_node eth1=$eth1_node"
return 0
}
case "${1:-start}" in
start|restart)
start_mapping
;;
stop)
;;
status)
eth0_node=$(node_for_interface eth0 2>/dev/null || echo missing)
eth1_node=$(node_for_interface eth1 2>/dev/null || echo missing)
echo "eth0=$eth0_node"
echo "eth1=$eth1_node"
if [ "$eth0_node" = "$TARGET_ETH0_NODE" ] && \
[ "$eth1_node" = "$TARGET_ETH1_NODE" ]; then
exit 0
fi
exit 1
;;
*)
echo "Usage: $0 {start|stop|restart|status}" >&2
exit 2
;;
esac