Skip to content

Commit b6f6cd4

Browse files
widoclaude
andcommitted
modifymacip.sh: drop state file, discover entries from bridge on delete
The state file was fragile: it could be left behind after a crash or missed during host migration. Delete now queries the bridge neighbour table directly with 'ip neigh show dev <bridge>' and removes every entry whose lladdr matches the MAC, along with its corresponding host route. This makes delete idempotent and self-healing without any persistent state on disk. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 366726c commit b6f6cd4

1 file changed

Lines changed: 13 additions & 47 deletions

File tree

scripts/vm/network/vnet/modifymacip.sh

Lines changed: 13 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@
2424
#
2525
# Both -4 and -6 may be specified multiple times to cover primary and secondary
2626
# addresses (e.g. link-local + global unicast for IPv6).
27-
# On add the script persists the NIC's address info so that delete can
28-
# recover the IPs without them being passed explicitly.
29-
30-
STATE_DIR=/var/run/cloud/macip
27+
# On delete the bridge neighbour table is queried for all entries matching the
28+
# MAC address; no separate state file is required.
3129

3230
usage() {
3331
echo "Usage: $0 -o <add|delete> -b <bridge> -m <mac> [-4 <ipv4>] ... [-6 <ipv6>] ..."
@@ -55,24 +53,7 @@ if [[ -z "$OP" || -z "$BRIDGE" || -z "$MAC" ]]; then
5553
exit 2
5654
fi
5755

58-
# Normalise MAC address for use as a filename (replace colons with underscores)
59-
MAC_NORM="${MAC//:/_}"
60-
STATE_FILE="${STATE_DIR}/${MAC_NORM}.conf"
61-
6256
add_entries() {
63-
mkdir -p "${STATE_DIR}"
64-
65-
# Persist state so that delete can recover IPs without them being passed in
66-
{
67-
for addr in "${IPV4_LIST[@]}"; do
68-
printf 'IPV4=%s\n' "${addr}"
69-
done
70-
for addr in "${IPV6_LIST[@]}"; do
71-
printf 'IPV6=%s\n' "${addr}"
72-
done
73-
printf 'BRIDGE=%s\n' "${BRIDGE}"
74-
} > "${STATE_FILE}"
75-
7657
for addr in "${IPV4_LIST[@]}"; do
7758
ip neigh replace "${addr}" lladdr "${MAC}" dev "${BRIDGE}" nud permanent
7859
ip route replace "${addr}/32" dev "${BRIDGE}"
@@ -89,32 +70,17 @@ add_entries() {
8970
}
9071

9172
delete_entries() {
92-
local -a del_ipv4=()
93-
local -a del_ipv6=()
94-
local del_bridge="${BRIDGE}"
95-
96-
# Recover IPs and bridge from the state file written at add time
97-
if [[ -f "${STATE_FILE}" ]]; then
98-
while IFS='=' read -r key value; do
99-
case "$key" in
100-
IPV4) [[ -n "$value" ]] && del_ipv4+=("$value") ;;
101-
IPV6) [[ -n "$value" ]] && del_ipv6+=("$value") ;;
102-
BRIDGE) del_bridge="${del_bridge:-$value}" ;;
103-
esac
104-
done < "${STATE_FILE}"
105-
fi
106-
107-
for addr in "${del_ipv4[@]}"; do
108-
ip neigh del "${addr}" dev "${del_bridge}" 2>/dev/null || true
109-
ip route del "${addr}/32" dev "${del_bridge}" 2>/dev/null || true
110-
done
111-
112-
for addr in "${del_ipv6[@]}"; do
113-
ip -6 neigh del "${addr}" dev "${del_bridge}" 2>/dev/null || true
114-
ip -6 route del "${addr}/128" dev "${del_bridge}" 2>/dev/null || true
115-
done
116-
117-
rm -f "${STATE_FILE}"
73+
# Find all IPv4 neighbour entries on the bridge matching this MAC and remove them
74+
while read -r addr; do
75+
ip neigh del "${addr}" dev "${BRIDGE}" 2>/dev/null || true
76+
ip route del "${addr}/32" dev "${BRIDGE}" 2>/dev/null || true
77+
done < <(ip neigh show dev "${BRIDGE}" | awk -v mac="${MAC}" 'tolower($3) == tolower(mac) {print $1}')
78+
79+
# Find all IPv6 neighbour entries on the bridge matching this MAC and remove them
80+
while read -r addr; do
81+
ip -6 neigh del "${addr}" dev "${BRIDGE}" 2>/dev/null || true
82+
ip -6 route del "${addr}/128" dev "${BRIDGE}" 2>/dev/null || true
83+
done < <(ip -6 neigh show dev "${BRIDGE}" | awk -v mac="${MAC}" 'tolower($3) == tolower(mac) {print $1}')
11884
}
11985

12086
case "$OP" in

0 commit comments

Comments
 (0)