Files
RouterOS/RouterOSAssistant/Features/Wizard/Steps/Setup/VlanStepView.swift
T
KayandClaude Sonnet 5 5c8b5fd9d2 M8: Mehrere LAN-Interfaces + Netzwerk-Isolation (Firewall-Regeln pro Netzwerk)
lanConfig wird zu lanConfigs: [LanDhcpConfig] (analog zum VLAN-Listen-
Muster) — mehrere physische Interfaces mit je eigenem DHCP-Server.
Neues isolated-Feld auf LanDhcpConfig/VlanEntry: FirewallConfig erzeugt
daraus paarweise Forward-Drop-Regeln zwischen jedem isolierten Netzwerk
und allen anderen konfigurierten Netzwerken (Pair-Dedup bei gegenseitiger
Isolation). Behebt nebenbei, dass VlanStepView bisher Isolation im
Hilfetext behauptete, ohne dass eine Regel das durchsetzte.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYoWFMLHACvzzRC8u4iKF9
2026-09-13 19:57:15 +02:00

71 lines
3.7 KiB
Swift

import SwiftUI
struct VlanStepView: View {
@ObservedObject var viewModel: SetupViewModel
let availableInterfaces: [NetworkInterface]
var body: some View {
Form {
Section {
Toggle(
"Zusätzliches Netzwerk einrichten (VLAN, optional)",
isOn: Binding(
get: { viewModel.vlanSectionEnabled },
set: { viewModel.setVlanSectionEnabled($0) }
)
)
.help("Erstellt ein zusätzliches Netzwerk mit eigenem Adressbereich und eigenem DHCP-Server.")
Text("Ein VLAN ist ein zusätzliches Netzwerk mit eigenem Adressbereich — z.B. für Gäste oder smarte Geräte. Ob es vom Hauptnetzwerk abgeschottet ist, legst du unten pro Netzwerk über \"Von anderen Netzwerken isolieren\" fest. Wenn du unsicher bist, ob du das brauchst, überspring diesen Schritt einfach.")
.font(.caption)
.foregroundStyle(.secondary)
}
if viewModel.vlanSectionEnabled {
ForEach($viewModel.vlans) { $vlan in
Section("Netzwerk \"\(vlan.name)\"") {
TextField("Name", text: $vlan.name)
.help("Ein Name zur Wiedererkennung, z.B. \"Gäste\" oder \"Smart Home\".")
Stepper("VLAN-ID: \(vlan.vlanID)", value: $vlan.vlanID, in: 2...4094)
.help("Eine eindeutige Nummer zur technischen Unterscheidung dieses Netzwerks. Muss nur innerhalb deines Routers einmalig sein.")
Picker("Basis-Anschluss", selection: $vlan.parentInterface) {
ForEach(availableInterfaces) { interface in
Text(interface.name).tag(interface.name)
}
}
.help("Der physische Anschluss, auf dem dieses zusätzliche Netzwerk aufbaut.")
TextField("Router-Adresse (z.B. 192.168.20.1/24)", text: $vlan.routerAddress)
.help("Die Adresse des Routers innerhalb dieses zusätzlichen Netzwerks.")
TextField("Netzwerk (z.B. 192.168.20.0/24)", text: $vlan.networkAddress)
.help("Der komplette Adressbereich dieses zusätzlichen Netzwerks.")
TextField("Automatische Adressvergabe von", text: $vlan.poolRangeStart)
.help("Ab welcher Adresse Geräte in diesem Netzwerk automatisch eine Adresse bekommen.")
TextField("bis", text: $vlan.poolRangeEnd)
.help("Bis zu welcher Adresse Geräte in diesem Netzwerk automatisch eine Adresse bekommen.")
Toggle("Von anderen Netzwerken isolieren", isOn: $vlan.isolated)
.help("Verhindert Datenverkehr zwischen diesem und allen anderen konfigurierten LAN-/VLAN-Netzwerken. Der Internetzugriff bleibt erhalten. Wird im Firewall-Schritt umgesetzt.")
Button("Netzwerk entfernen", role: .destructive) {
viewModel.removeVlan(vlan.id)
}
}
}
Button("Weiteres Netzwerk hinzufügen") {
viewModel.addVlan()
}
}
Section {
HStack {
Button("Zurück") { viewModel.goBack() }
Spacer()
Button("Weiter") { viewModel.goNext() }
}
}
}
.formStyle(.grouped)
.navigationTitle("Zusätzliche Netzwerke (VLAN)")
}
}