fix(vlans): robust bridge-IP removal; record cutover + gotchas
RouterOS 'find ... address=<prefix>' never matches an ip/address value, so the legacy-bridge-IP removal is now a :foreach get-and-compare. Refresh the committed export.rsc to the post-cutover config (flat VLAN 30 + isolated mgmt VLAN 99 on ether8, vlan-filtering on). Spec updated with execution notes (NM autoconnect flap, the find-address quirk, and the commit-confirmed detached-flip technique used). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ebd21623ef
commit
199edf85ad
3 changed files with 44 additions and 22 deletions
|
|
@ -1,26 +1,30 @@
|
||||||
# 2025-09-11 09:49:07 by RouterOS 7.19.6
|
# 2025-09-11 10:03:39 by RouterOS 7.19.6
|
||||||
# software id = 73S3-5F2W
|
# software id = 73S3-5F2W
|
||||||
#
|
#
|
||||||
# model = CRS310-8G+2S+
|
# model = CRS310-8G+2S+
|
||||||
# serial number = HM40B8TDNDD
|
# serial number = HM40B8TDNDD
|
||||||
/interface bridge
|
/interface bridge
|
||||||
add admin-mac=D0:EA:11:24:F4:AA auto-mac=no comment=defconf name=bridge
|
add admin-mac=D0:EA:11:24:F4:AA auto-mac=no comment=defconf name=bridge \
|
||||||
|
vlan-filtering=yes
|
||||||
|
/interface vlan
|
||||||
|
add interface=bridge name=vlan-mgmt vlan-id=99
|
||||||
/interface bridge port
|
/interface bridge port
|
||||||
add bridge=bridge comment=defconf interface=ether1
|
add bridge=bridge comment=defconf interface=ether1 pvid=30
|
||||||
add bridge=bridge comment=defconf interface=ether2
|
add bridge=bridge comment=defconf interface=ether2 pvid=30
|
||||||
add bridge=bridge comment=defconf interface=ether3
|
add bridge=bridge comment=defconf interface=ether3 pvid=30
|
||||||
add bridge=bridge comment=defconf interface=ether4
|
add bridge=bridge comment=defconf interface=ether4 pvid=30
|
||||||
add bridge=bridge comment=defconf interface=ether5
|
add bridge=bridge comment=defconf interface=ether5 pvid=30
|
||||||
add bridge=bridge comment=defconf interface=ether6
|
add bridge=bridge comment=defconf interface=ether6 pvid=30
|
||||||
add bridge=bridge comment=defconf interface=ether7
|
add bridge=bridge comment=defconf interface=ether7 pvid=30
|
||||||
add bridge=bridge comment=defconf interface=ether8
|
add bridge=bridge comment=defconf interface=ether8 pvid=99
|
||||||
add bridge=bridge comment=defconf interface=sfp-sfpplus1
|
add bridge=bridge comment=defconf interface=sfp-sfpplus1 pvid=30
|
||||||
add bridge=bridge comment=defconf interface=sfp-sfpplus2
|
add bridge=bridge comment=defconf interface=sfp-sfpplus2 pvid=30
|
||||||
|
/interface bridge vlan
|
||||||
|
add bridge=bridge untagged="ether1,ether2,ether3,ether4,ether5,ether6,ether7,s\
|
||||||
|
fp-sfpplus1,sfp-sfpplus2" vlan-ids=30
|
||||||
|
add bridge=bridge tagged=bridge untagged=ether8 vlan-ids=99
|
||||||
/ip address
|
/ip address
|
||||||
add address=192.168.88.1/24 comment=defconf interface=bridge network=\
|
add address=192.168.88.1/24 interface=vlan-mgmt network=192.168.88.0
|
||||||
192.168.88.0
|
|
||||||
/ip dns
|
|
||||||
set servers=10.0.99.1
|
|
||||||
/ip service
|
/ip service
|
||||||
set ftp disabled=yes
|
set ftp disabled=yes
|
||||||
set telnet disabled=yes
|
set telnet disabled=yes
|
||||||
|
|
@ -29,7 +33,5 @@ set api disabled=yes
|
||||||
set api-ssl disabled=yes
|
set api-ssl disabled=yes
|
||||||
/system identity
|
/system identity
|
||||||
set name=crs310-maker
|
set name=crs310-maker
|
||||||
/system ntp client
|
|
||||||
set enabled=yes
|
|
||||||
/system ntp client servers
|
/system ntp client servers
|
||||||
add address=10.0.99.1
|
add address=10.0.99.1
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,25 @@ all-access topology (DATA untagged = data ports, CPU tagged only on MGMT).
|
||||||
- **Removing the legacy bridge IP** is the delicate step — done while the new
|
- **Removing the legacy bridge IP** is the delicate step — done while the new
|
||||||
`vlan-mgmt` IP is the same address, before filtering, with the connection watched.
|
`vlan-mgmt` IP is the same address, before filtering, with the connection watched.
|
||||||
|
|
||||||
|
## Execution notes (applied 2026-06-09)
|
||||||
|
|
||||||
|
Cutover completed; switch is VLAN-filtered with isolated mgmt reachable on `ether8`.
|
||||||
|
`play_switch.yml` runs idempotently over the new mgmt path. Two gotchas surfaced:
|
||||||
|
|
||||||
|
- **NetworkManager autoconnect flap:** moving mamba's cable bounced the link; NM
|
||||||
|
re-selected the DHCP profile and dropped the static mgmt IP. Fixed by making
|
||||||
|
`crs310-bench` (192.168.88.2) sticky (`autoconnect yes`, priority 10) and turning
|
||||||
|
`autoconnect off` on `Wired connection 1`.
|
||||||
|
- **RouterOS `find ... address=<prefix>` never matches** an `/ip/address` value (returns
|
||||||
|
0 even on an exact string). The first flip therefore failed to remove the defconf IP
|
||||||
|
off `bridge`, duplicating `192.168.88.1` onto `vlan-mgmt` and breaking ARP. Fix: remove
|
||||||
|
by `[find interface=bridge]`, or match via `:foreach`+`/ip/address/get $a address`.
|
||||||
|
- **The flip was run as a detached, self-reverting on-device job** (`:execute { … :delay
|
||||||
|
240s; :if ($mgmtok=false) do={ revert } }`) — a commit-confirmed pattern. The first
|
||||||
|
(failed) attempt auto-healed at the timer; the corrected attempt was confirmed by
|
||||||
|
setting `:global mgmtok true` within the window. Recommended for any future
|
||||||
|
`vlan-filtering`/mgmt-IP change made over the network.
|
||||||
|
|
||||||
## Out of scope
|
## Out of scope
|
||||||
|
|
||||||
Real inter-VLAN segmentation, the SFP+ 10G uplink/trunk, and any upstream router VLAN
|
Real inter-VLAN segmentation, the SFP+ 10G uplink/trunk, and any upstream router VLAN
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,14 @@
|
||||||
# detached flip (see the design doc's runbook), not by a straight play run. In steady
|
# detached flip (see the design doc's runbook), not by a straight play run. In steady
|
||||||
# state both tasks below are no-ops.
|
# state both tasks below are no-ops.
|
||||||
- name: Remove the legacy management IP from the bare bridge interface
|
- name: Remove the legacy management IP from the bare bridge interface
|
||||||
|
# NOTE: RouterOS `find ... address=<v>` does NOT match an ip/address prefix value
|
||||||
|
# (it returns 0 even on an exact string), so match by get-and-compare instead.
|
||||||
community.routeros.command:
|
community.routeros.command:
|
||||||
commands:
|
commands:
|
||||||
- >-
|
- >-
|
||||||
:if ([:len [/ip/address/find interface="{{ switch_bridge_name }}"
|
:foreach a in=[/ip/address/find interface="{{ switch_bridge_name }}"]
|
||||||
address="{{ switch_mgmt_address }}"]] > 0)
|
do={ :if ([/ip/address/get $a address]="{{ switch_mgmt_address }}")
|
||||||
do={ /ip/address/remove [find interface="{{ switch_bridge_name }}"
|
do={ /ip/address/remove $a } }
|
||||||
address="{{ switch_mgmt_address }}"] }
|
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Assign the management IP address to vlan-mgmt
|
- name: Assign the management IP address to vlan-mgmt
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue