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
|
||||
#
|
||||
# model = CRS310-8G+2S+
|
||||
# serial number = HM40B8TDNDD
|
||||
/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
|
||||
add bridge=bridge comment=defconf interface=ether1
|
||||
add bridge=bridge comment=defconf interface=ether2
|
||||
add bridge=bridge comment=defconf interface=ether3
|
||||
add bridge=bridge comment=defconf interface=ether4
|
||||
add bridge=bridge comment=defconf interface=ether5
|
||||
add bridge=bridge comment=defconf interface=ether6
|
||||
add bridge=bridge comment=defconf interface=ether7
|
||||
add bridge=bridge comment=defconf interface=ether8
|
||||
add bridge=bridge comment=defconf interface=sfp-sfpplus1
|
||||
add bridge=bridge comment=defconf interface=sfp-sfpplus2
|
||||
add bridge=bridge comment=defconf interface=ether1 pvid=30
|
||||
add bridge=bridge comment=defconf interface=ether2 pvid=30
|
||||
add bridge=bridge comment=defconf interface=ether3 pvid=30
|
||||
add bridge=bridge comment=defconf interface=ether4 pvid=30
|
||||
add bridge=bridge comment=defconf interface=ether5 pvid=30
|
||||
add bridge=bridge comment=defconf interface=ether6 pvid=30
|
||||
add bridge=bridge comment=defconf interface=ether7 pvid=30
|
||||
add bridge=bridge comment=defconf interface=ether8 pvid=99
|
||||
add bridge=bridge comment=defconf interface=sfp-sfpplus1 pvid=30
|
||||
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
|
||||
add address=192.168.88.1/24 comment=defconf interface=bridge network=\
|
||||
192.168.88.0
|
||||
/ip dns
|
||||
set servers=10.0.99.1
|
||||
add address=192.168.88.1/24 interface=vlan-mgmt network=192.168.88.0
|
||||
/ip service
|
||||
set ftp disabled=yes
|
||||
set telnet disabled=yes
|
||||
|
|
@ -29,7 +33,5 @@ set api disabled=yes
|
|||
set api-ssl disabled=yes
|
||||
/system identity
|
||||
set name=crs310-maker
|
||||
/system ntp client
|
||||
set enabled=yes
|
||||
/system ntp client servers
|
||||
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
|
||||
`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
|
||||
|
||||
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
|
||||
# state both tasks below are no-ops.
|
||||
- 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:
|
||||
commands:
|
||||
- >-
|
||||
:if ([:len [/ip/address/find interface="{{ switch_bridge_name }}"
|
||||
address="{{ switch_mgmt_address }}"]] > 0)
|
||||
do={ /ip/address/remove [find interface="{{ switch_bridge_name }}"
|
||||
address="{{ switch_mgmt_address }}"] }
|
||||
:foreach a in=[/ip/address/find interface="{{ switch_bridge_name }}"]
|
||||
do={ :if ([/ip/address/get $a address]="{{ switch_mgmt_address }}")
|
||||
do={ /ip/address/remove $a } }
|
||||
changed_when: false
|
||||
|
||||
- name: Assign the management IP address to vlan-mgmt
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue