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
3230usage () {
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
5654fi
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-
6256add_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
9172delete_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
12086case " $OP " in
0 commit comments