From b0009fbb1fa72b9a83342241112a7bf2140f4ac5 Mon Sep 17 00:00:00 2001 From: shats Date: Tue, 26 Aug 2025 20:29:26 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BE=D0=BF=D1=86=D0=B8=D1=8E=20=D0=B0=D0=B3?= =?UTF-8?q?=D1=80=D0=B5=D1=81=D1=81=D0=B8=D0=B2=D0=BD=D0=BE=D0=B9=20=D0=B0?= =?UTF-8?q?=D0=B3=D1=80=D0=B5=D0=B3=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20IP-=D0=B4=D0=B8=D0=B0=D0=BF=D0=B0=D0=B7=D0=BE=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2,=20=D0=BF=D0=BE=D0=B7=D0=B2=D0=BE=D0=BB=D1=8F?= =?UTF-8?q?=D1=8E=D1=89=D1=83=D1=8E=20=D1=81=D0=B2=D0=BE=D1=80=D0=B0=D1=87?= =?UTF-8?q?=D0=B8=D0=B2=D0=B0=D1=82=D1=8C=20=D0=B1=D0=BE=D0=BB=D0=B5=D0=B5?= =?UTF-8?q?=202=20=D0=BF=D1=80=D0=B5=D1=84=D0=B8=D0=BA=D1=81=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B2=20=D0=BE=D0=B4=D0=BD=D0=BE=D0=BC=20/16;=20=D0=BE?= =?UTF-8?q?=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8=D1=82=D1=8C=20=D0=B8=D0=BD=D1=82?= =?UTF-8?q?=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=8D=D1=82=D0=BE=D0=B9=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=B9=D0=BA=D0=BE=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/IPRangesManager.jsx | 38 ++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/frontend/src/IPRangesManager.jsx b/frontend/src/IPRangesManager.jsx index 2f80ca8..a3c8084 100644 --- a/frontend/src/IPRangesManager.jsx +++ b/frontend/src/IPRangesManager.jsx @@ -228,7 +228,7 @@ function IPRangesManager() { const [analysisResultsOpen, setAnalysisResultsOpen] = useState(false); const [analysisPreview, setAnalysisPreview] = useState(null); const [overwriteConfirmOpen, setOverwriteConfirmOpen] = useState(false); - const [analyzeFilters, setAnalyzeFilters] = useState({ community: '', minMask: 0, maxMask: 32, type: 'any' }); + const [analyzeFilters, setAnalyzeFilters] = useState({ community: '', minMask: 0, maxMask: 32, type: 'any', supernet16: false }); const handlePreviewDiff = () => { const valid = items.filter(i => isValidCidr(i.ipRange) && isValidCommunity(i.community)) @@ -437,6 +437,7 @@ function IPRangesManager() { parts.push(`Маска: /${analyzeFilters.minMask}..../${analyzeFilters.maxMask}`); const typeLabel = analyzeFilters.type === 'any' ? 'любой' : (analyzeFilters.type === 'private' ? 'только приватные' : (analyzeFilters.type === 'public' ? 'только публичные' : 'только CGNAT')); parts.push(`Тип: ${typeLabel}`); + parts.push(`Агрегировать >2 префиксов в одном /16 до /16: ${analyzeFilters.supernet16 ? 'да' : 'нет'}`); return parts.join('\n'); }; @@ -522,6 +523,28 @@ function IPRangesManager() { return out; }; + // Агрессивная агрегация: если в одном /16 > 2 префиксов — свернуть в /16 + const get16BaseCidr = (cidr) => { + const ip = String(cidr).split('/')[0]; + const ipNum = ipToInt(ip); + const start = ipNum & (~0n << 16n); + return `${intToIp(start)}/16`; + }; + + const applySupernet16 = (cidrs) => { + const buckets = new Map(); + for (const c of cidrs) { + const base16 = get16BaseCidr(c); + if (!buckets.has(base16)) buckets.set(base16, []); + buckets.get(base16).push(c); + } + const out = []; + for (const [base16, list] of buckets) { + if (list.length > 2) out.push(base16); else out.push(...list); + } + return Array.from(new Set(out)); + }; + const runAnalysis = () => { const community = String(analyzeFilters.community || '').trim(); if (!community) { window.notify?.error?.('Выберите community'); return; } @@ -539,7 +562,10 @@ function IPRangesManager() { const unchanged = allForCommunity.filter(i => !filtered.includes(i)); const beforeCidrs = filtered.map(i => i.ipRange); - const afterCidrs = summarizeCidrs(beforeCidrs); + let afterCidrs = summarizeCidrs(beforeCidrs); + if (analyzeFilters.supernet16) { + afterCidrs = applySupernet16(afterCidrs); + } const processedBefore = beforeCidrs.length; const processedAfter = afterCidrs.length; const totalAfter = processedAfter + unchanged.length; @@ -1018,6 +1044,14 @@ function IPRangesManager() {
Определение типа по первому IP в CIDR.
+
+ + +
Например: 157.240.12.0/23, 157.240.15.0/24, 157.240.16.0/23 → 157.240.0.0/16
+