fix(vxlan): подтвердить достоверность опроса и экспорта раздела

This commit is contained in:
Denozordec committed 2026-10-09 10:38:24 +07:00
1 parent 6b068ac39a
commit e2d81f9657
23 files changed
+689 -89

No files matched your search

+1
View File
@@ -212,6 +212,7 @@ export interface VxlanTunnel {
vtepIp: string // VTEP address on the server
remoteVteps: string[] // remote VTEP IPs (unicast-flood)
l2mtu: number
mtu?: number // actual interface MTU; absent in legacy snapshots
arpProxy: boolean
arpMode?: "disabled" | "enabled" | "local-proxy-arp" | "proxy-arp" | "reply-only"
macLearning: boolean
+3
View File
@@ -16,3 +16,6 @@ const noLocal = generateVxlanRsc({ ...tunnel, vtepIp: "", arpMode: undefined, ar
assert.ok(!noLocal.includes("local-address="))
assert.ok(noLocal.includes('arp="proxy-arp"'))
console.log("vxlan-export: quoted strings, supported properties and no invented bridge passed")
assert.match(generateVxlanRsc({ ...tunnel, mtu: 1400 }, {}), /mtu=1400/)
assert.ok(!code.includes("mtu=1500"))
assert.match(code, /MTU в снимке отсутствует/)
+3 -1
View File
@@ -15,7 +15,7 @@ export function generateVxlanRsc(t: VxlanTunnel, servers: Record<string, Server>
const server = servers[t.serverId]
const lines = [`# VXLAN — ${commentLine(t.name)} · VNI ${t.vni}`]
if (server) lines.push(`# Сервер: ${commentLine(server.name)} (${commentLine(server.host)})`)
lines.push("# RouterOS 7.x · интерфейс и статические VTEP; bridge/FDB не включены", "")
lines.push("# RouterOS 7.x · интерфейс и статические VTEP; IP-адреса, bridge/FDB не включены", "")
const args = [
`name=${quoteRosString(t.name)}`, `vni=${t.vni}`, `port=${t.dstPort}`,
`arp=${quoteRosString(t.arpMode ?? (t.arpProxy ? "proxy-arp" : "enabled"))}`,
@@ -23,6 +23,8 @@ export function generateVxlanRsc(t: VxlanTunnel, servers: Record<string, Server>
`comment=${quoteRosString(t.comment)}`,
]
if (t.vtepIp) args.push(`local-address=${quoteRosString(t.vtepIp)}`)
if (t.mtu !== undefined) args.push(`mtu=${t.mtu}`)
else lines.push("# MTU в снимке отсутствует: проверьте его перед применением")
lines.push("/interface/vxlan/add " + args.join(" "))
for (const remote of t.remoteVteps) lines.push(`/interface/vxlan/vteps/add interface=${quoteRosString(t.name)} remote-ip=${quoteRosString(remote)}`)
return lines.join("\n") + "\n"
+1
View File
@@ -6,6 +6,7 @@ export const vxlanResponseSchema = z.object({
vni: z.number().int().min(0).max(16777215),
port: z.number().int().min(0).max(65535), dstPort: z.number().int().min(1).max(65535),
vtepIp: z.string(), remoteVteps: z.array(z.string()), l2mtu: z.number().int().nonnegative(),
mtu: z.number().int().min(1).max(65535).optional(),
arpProxy: z.boolean(), arpMode: z.enum(["disabled", "enabled", "local-proxy-arp", "proxy-arp", "reply-only"]).optional(), macLearning: z.boolean(), comment: z.string(), enabled: z.boolean(),
status: z.enum(["up", "down"]),
})).refine(rows => new Set(rows.map(row => JSON.stringify([row.serverId, row.id]))).size === rows.length && rows.every(row => row.arpMode === undefined || row.arpProxy === (row.arpMode === "proxy-arp" || row.arpMode === "local-proxy-arp"))),