|
@@ -2687,6 +2687,17 @@ function renderFilterRules() {
|
|
|
const ports = [r.src_port ? 's:' + r.src_port : '', r.dst_port ? 'd:' + r.dst_port : ''].filter(Boolean).join(' ');
|
|
const ports = [r.src_port ? 's:' + r.src_port : '', r.dst_port ? 'd:' + r.dst_port : ''].filter(Boolean).join(' ');
|
|
|
const ifaces = [r.in_interface ? 'in:' + r.in_interface : '', r.out_interface ? 'out:' + r.out_interface : ''].filter(Boolean).join(' ');
|
|
const ifaces = [r.in_interface ? 'in:' + r.in_interface : '', r.out_interface ? 'out:' + r.out_interface : ''].filter(Boolean).join(' ');
|
|
|
|
|
|
|
|
|
|
+ let actionExtra = '';
|
|
|
|
|
+ if (r.action === 'reject') {
|
|
|
|
|
+ actionExtra = `<span class="block text-[10px] text-rose-300 font-mono mt-0.5">(${r.reject_with || 'icmp-net-unreach'})</span>`;
|
|
|
|
|
+ } else if (r.action === 'jump') {
|
|
|
|
|
+ actionExtra = `<span class="block text-[10px] text-yellow-300 font-mono mt-0.5">→ ${r.jump_target || '-'}</span>`;
|
|
|
|
|
+ } else if (r.action.includes('address-list') || r.action.includes('address list')) {
|
|
|
|
|
+ actionExtra = `<span class="block text-[10px] text-emerald-300 font-mono mt-0.5">→ ${r.address_list || '-'}</span>`;
|
|
|
|
|
+ } else if (r.action === 'log' && r.log_prefix) {
|
|
|
|
|
+ actionExtra = `<span class="block text-[10px] text-slate-400 font-mono mt-0.5">${r.log_prefix}</span>`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
tr.innerHTML = `
|
|
tr.innerHTML = `
|
|
|
<td class="py-2.5 px-3 text-center text-slate-500 font-bold">${r.order || idx + 1}</td>
|
|
<td class="py-2.5 px-3 text-center text-slate-500 font-bold">${r.order || idx + 1}</td>
|
|
|
<td class="py-2.5 px-3 text-center">${renderRuleFlag(r.disabled, !!r.comment)}</td>
|
|
<td class="py-2.5 px-3 text-center">${renderRuleFlag(r.disabled, !!r.comment)}</td>
|
|
@@ -2696,7 +2707,7 @@ function renderFilterRules() {
|
|
|
<td class="py-2.5 px-3 text-cyan-400 uppercase">${r.protocol || 'all'}</td>
|
|
<td class="py-2.5 px-3 text-cyan-400 uppercase">${r.protocol || 'all'}</td>
|
|
|
<td class="py-2.5 px-3 text-amber-400">${ports || '-'}</td>
|
|
<td class="py-2.5 px-3 text-amber-400">${ports || '-'}</td>
|
|
|
<td class="py-2.5 px-3 text-emerald-400">${ifaces || '-'}</td>
|
|
<td class="py-2.5 px-3 text-emerald-400">${ifaces || '-'}</td>
|
|
|
- <td class="py-2.5 px-3">${renderActionBadge(r.action)}</td>
|
|
|
|
|
|
|
+ <td class="py-2.5 px-3">${renderActionBadge(r.action)}${actionExtra}</td>
|
|
|
<td class="py-2.5 px-3 text-[11px] text-slate-400">
|
|
<td class="py-2.5 px-3 text-[11px] text-slate-400">
|
|
|
<span class="text-slate-300">${(r.packets || 0).toLocaleString()}p</span> /
|
|
<span class="text-slate-300">${(r.packets || 0).toLocaleString()}p</span> /
|
|
|
<span class="text-slate-500">${formatTraffic(r.bytes || 0).replace('/s', '')}</span>
|
|
<span class="text-slate-500">${formatTraffic(r.bytes || 0).replace('/s', '')}</span>
|
|
@@ -2767,6 +2778,19 @@ function populateAddressListSelect(selectId, currentVal = '') {
|
|
|
opt.selected = true;
|
|
opt.selected = true;
|
|
|
sel.appendChild(opt);
|
|
sel.appendChild(opt);
|
|
|
}
|
|
}
|
|
|
|
|
+ populateCommonAddrListDatalist();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function populateCommonAddrListDatalist() {
|
|
|
|
|
+ const dl = document.getElementById('fw-addrlist-datalist');
|
|
|
|
|
+ if (!dl) return;
|
|
|
|
|
+ dl.innerHTML = '';
|
|
|
|
|
+ const names = Array.from(new Set((state.addressLists || []).map(a => a.name).filter(Boolean))).sort();
|
|
|
|
|
+ names.forEach(name => {
|
|
|
|
|
+ const opt = document.createElement('option');
|
|
|
|
|
+ opt.value = name;
|
|
|
|
|
+ dl.appendChild(opt);
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function populateGeoIPSelect(selectId, currentVal = '') {
|
|
function populateGeoIPSelect(selectId, currentVal = '') {
|
|
@@ -3116,9 +3140,22 @@ function toggleFilterActionFields() {
|
|
|
else jumpBox.classList.add('hidden');
|
|
else jumpBox.classList.add('hidden');
|
|
|
}
|
|
}
|
|
|
if (addrBox) {
|
|
if (addrBox) {
|
|
|
- if (act === 'add-dst-to-address-list' || act === 'add-src-to-address-list') addrBox.classList.remove('hidden');
|
|
|
|
|
- else addrBox.classList.add('hidden');
|
|
|
|
|
|
|
+ if (act === 'add-dst-to-address-list' || act === 'add-src-to-address-list' || act.includes('address-list') || act.includes('address list')) {
|
|
|
|
|
+ addrBox.classList.remove('hidden');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ addrBox.classList.add('hidden');
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ if (act === 'log') {
|
|
|
|
|
+ const logEl = document.getElementById('filter-modal-log');
|
|
|
|
|
+ if (logEl) logEl.checked = true;
|
|
|
|
|
+ toggleFwField('logprefix', true);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function toggleFwLogPrefix() {
|
|
|
|
|
+ const isLog = document.getElementById('filter-modal-log')?.checked;
|
|
|
|
|
+ toggleFwField('logprefix', !!isLog);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function copyFilterRule() {
|
|
function copyFilterRule() {
|
|
@@ -3481,7 +3518,22 @@ function renderNATRules() {
|
|
|
rules.forEach((r, idx) => {
|
|
rules.forEach((r, idx) => {
|
|
|
const tr = document.createElement('tr');
|
|
const tr = document.createElement('tr');
|
|
|
tr.className = `hover:bg-slate-800/40 transition text-xs ${r.disabled ? 'opacity-50' : ''}`;
|
|
tr.className = `hover:bg-slate-800/40 transition text-xs ${r.disabled ? 'opacity-50' : ''}`;
|
|
|
- const toTarget = [r.to_addresses, r.to_ports].filter(Boolean).join(':');
|
|
|
|
|
|
|
+
|
|
|
|
|
+ let toTarget = '-';
|
|
|
|
|
+ if (r.action === 'jump') {
|
|
|
|
|
+ toTarget = `<span class="text-yellow-300 font-mono font-bold">→ ${r.jump_target || '-'}</span>`;
|
|
|
|
|
+ } else if (r.action.includes('address-list') || r.action.includes('address list')) {
|
|
|
|
|
+ toTarget = `<span class="text-emerald-300 font-mono font-bold">→ ${r.address_list || '-'}</span>`;
|
|
|
|
|
+ } else if (r.action === 'redirect') {
|
|
|
|
|
+ toTarget = `<span class="text-amber-300 font-mono font-bold">ports:${r.to_ports || 'all'}</span>`;
|
|
|
|
|
+ } else if (r.action === 'masquerade') {
|
|
|
|
|
+ toTarget = r.to_ports ? `<span class="text-amber-300 font-mono font-bold">ports:${r.to_ports}</span>` : `<span class="text-slate-500 font-mono">-</span>`;
|
|
|
|
|
+ } else if (r.action === 'log') {
|
|
|
|
|
+ toTarget = `<span class="text-slate-400 font-mono font-bold">${r.log_prefix || 'log'}</span>`;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const parts = [r.to_addresses, r.to_ports].filter(Boolean);
|
|
|
|
|
+ toTarget = parts.length ? `<span class="text-amber-300 font-mono font-bold">${parts.join(':')}</span>` : '-';
|
|
|
|
|
+ }
|
|
|
const ifaces = [r.out_interface ? 'out:' + r.out_interface : '', r.in_interface ? 'in:' + r.in_interface : ''].filter(Boolean).join(' ');
|
|
const ifaces = [r.out_interface ? 'out:' + r.out_interface : '', r.in_interface ? 'in:' + r.in_interface : ''].filter(Boolean).join(' ');
|
|
|
|
|
|
|
|
tr.innerHTML = `
|
|
tr.innerHTML = `
|
|
@@ -3493,7 +3545,7 @@ function renderNATRules() {
|
|
|
<td class="py-2.5 px-3 text-cyan-400 uppercase">${r.protocol || 'all'}${r.dst_port ? ':' + r.dst_port : ''}</td>
|
|
<td class="py-2.5 px-3 text-cyan-400 uppercase">${r.protocol || 'all'}${r.dst_port ? ':' + r.dst_port : ''}</td>
|
|
|
<td class="py-2.5 px-3 text-emerald-400">${ifaces || '-'}</td>
|
|
<td class="py-2.5 px-3 text-emerald-400">${ifaces || '-'}</td>
|
|
|
<td class="py-2.5 px-3">${renderActionBadge(r.action)}</td>
|
|
<td class="py-2.5 px-3">${renderActionBadge(r.action)}</td>
|
|
|
- <td class="py-2.5 px-3 font-mono font-bold text-amber-300">${toTarget || '-'}</td>
|
|
|
|
|
|
|
+ <td class="py-2.5 px-3 font-mono text-xs">${toTarget}</td>
|
|
|
<td class="py-2.5 px-3 text-[11px] text-slate-400">
|
|
<td class="py-2.5 px-3 text-[11px] text-slate-400">
|
|
|
<span class="text-slate-300">${(r.packets || 0).toLocaleString()}p</span> /
|
|
<span class="text-slate-300">${(r.packets || 0).toLocaleString()}p</span> /
|
|
|
<span class="text-slate-500">${formatTraffic(r.bytes || 0).replace('/s', '')}</span>
|
|
<span class="text-slate-500">${formatTraffic(r.bytes || 0).replace('/s', '')}</span>
|
|
@@ -3627,25 +3679,40 @@ function handleNATChainChange() {
|
|
|
|
|
|
|
|
function toggleNATActionFields() {
|
|
function toggleNATActionFields() {
|
|
|
const act = document.getElementById('nat-modal-action')?.value || 'masquerade';
|
|
const act = document.getElementById('nat-modal-action')?.value || 'masquerade';
|
|
|
- const toBox = document.getElementById('nat-action-to-box');
|
|
|
|
|
|
|
+ const rowAddr = document.getElementById('nat-row-toaddr');
|
|
|
|
|
+ const rowPort = document.getElementById('nat-row-toport');
|
|
|
const jumpBox = document.getElementById('nat-action-jump-box');
|
|
const jumpBox = document.getElementById('nat-action-jump-box');
|
|
|
const addrBox = document.getElementById('nat-action-addrlist-box');
|
|
const addrBox = document.getElementById('nat-action-addrlist-box');
|
|
|
|
|
|
|
|
- if (toBox) {
|
|
|
|
|
- const needsTo = ['src-nat', 'dst-nat', 'redirect', 'netmap', 'same', 'endpoint-independent-nat'].includes(act);
|
|
|
|
|
- if (needsTo) toBox.classList.remove('hidden');
|
|
|
|
|
- else toBox.classList.add('hidden');
|
|
|
|
|
- }
|
|
|
|
|
- if (jumpBox) {
|
|
|
|
|
- if (act === 'jump') jumpBox.classList.remove('hidden');
|
|
|
|
|
- else jumpBox.classList.add('hidden');
|
|
|
|
|
|
|
+ // Hide all dynamic rows first
|
|
|
|
|
+ if (rowAddr) rowAddr.classList.add('hidden');
|
|
|
|
|
+ if (rowPort) rowPort.classList.add('hidden');
|
|
|
|
|
+ if (jumpBox) jumpBox.classList.add('hidden');
|
|
|
|
|
+ if (addrBox) addrBox.classList.add('hidden');
|
|
|
|
|
+
|
|
|
|
|
+ if (['src-nat', 'dst-nat', 'netmap', 'same', 'socksify', 'endpoint-independent-nat'].includes(act)) {
|
|
|
|
|
+ if (rowAddr) rowAddr.classList.remove('hidden');
|
|
|
|
|
+ if (rowPort) rowPort.classList.remove('hidden');
|
|
|
|
|
+ } else if (act === 'redirect' || act === 'masquerade') {
|
|
|
|
|
+ if (rowPort) rowPort.classList.remove('hidden');
|
|
|
|
|
+ } else if (act === 'jump') {
|
|
|
|
|
+ if (jumpBox) jumpBox.classList.remove('hidden');
|
|
|
|
|
+ } else if (act.includes('address-list') || act.includes('address list')) {
|
|
|
|
|
+ if (addrBox) addrBox.classList.remove('hidden');
|
|
|
}
|
|
}
|
|
|
- if (addrBox) {
|
|
|
|
|
- if (act.includes('address-list') || act.includes('address list')) addrBox.classList.remove('hidden');
|
|
|
|
|
- else addrBox.classList.add('hidden');
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (act === 'log') {
|
|
|
|
|
+ const logEl = document.getElementById('nat-modal-log');
|
|
|
|
|
+ if (logEl) logEl.checked = true;
|
|
|
|
|
+ toggleNATField('logprefix', true);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function toggleNATLogPrefix() {
|
|
|
|
|
+ const isLog = document.getElementById('nat-modal-log')?.checked;
|
|
|
|
|
+ toggleNATField('logprefix', !!isLog);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
function openAddNATModal() {
|
|
function openAddNATModal() {
|
|
|
switchNATRuleTab('general');
|
|
switchNATRuleTab('general');
|
|
|
const badge = document.getElementById('nat-modal-badge');
|
|
const badge = document.getElementById('nat-modal-badge');
|
|
@@ -3853,12 +3920,15 @@ async function applyNATRule(closeAfter = false) {
|
|
|
const routingmark = getNATFieldVal('routingmark', true);
|
|
const routingmark = getNATFieldVal('routingmark', true);
|
|
|
const conntype = getNATFieldVal('conntype', false);
|
|
const conntype = getNATFieldVal('conntype', false);
|
|
|
|
|
|
|
|
|
|
+ const usesAddr = ['src-nat', 'dst-nat', 'netmap', 'same', 'socksify', 'endpoint-independent-nat'].includes(action);
|
|
|
|
|
+ const usesPort = ['src-nat', 'dst-nat', 'netmap', 'same', 'socksify', 'endpoint-independent-nat', 'redirect', 'masquerade'].includes(action);
|
|
|
|
|
+
|
|
|
const payload = {
|
|
const payload = {
|
|
|
id,
|
|
id,
|
|
|
chain,
|
|
chain,
|
|
|
action,
|
|
action,
|
|
|
- to_addresses: document.getElementById('nat-modal-toaddr')?.value.trim() || '',
|
|
|
|
|
- to_ports: document.getElementById('nat-modal-toport')?.value.trim() || '',
|
|
|
|
|
|
|
+ to_addresses: usesAddr ? (document.getElementById('nat-modal-toaddr')?.value.trim() || '') : '',
|
|
|
|
|
+ to_ports: usesPort ? (document.getElementById('nat-modal-toport')?.value.trim() || '') : '',
|
|
|
protocol: proto || 'all',
|
|
protocol: proto || 'all',
|
|
|
src_address: src,
|
|
src_address: src,
|
|
|
dst_address: dst,
|
|
dst_address: dst,
|
|
@@ -4077,7 +4147,19 @@ function renderMangleRules() {
|
|
|
rules.forEach((r, idx) => {
|
|
rules.forEach((r, idx) => {
|
|
|
const tr = document.createElement('tr');
|
|
const tr = document.createElement('tr');
|
|
|
tr.className = `hover:bg-slate-800/40 transition text-xs ${r.disabled ? 'opacity-50' : ''}`;
|
|
tr.className = `hover:bg-slate-800/40 transition text-xs ${r.disabled ? 'opacity-50' : ''}`;
|
|
|
- const markVal = r.new_connection_mark || r.new_routing_mark || r.new_packet_mark || r.new_mss || (r.new_dscp ? 'DSCP:' + r.new_dscp : '');
|
|
|
|
|
|
|
+ let markVal = '<span class="text-slate-500">-</span>';
|
|
|
|
|
+ if (r.new_connection_mark) markVal = `<span class="text-cyan-300 font-mono font-bold">${r.new_connection_mark}</span>`;
|
|
|
|
|
+ else if (r.new_routing_mark) markVal = `<span class="text-amber-300 font-mono font-bold">${r.new_routing_mark}</span>`;
|
|
|
|
|
+ else if (r.new_packet_mark) markVal = `<span class="text-emerald-300 font-mono font-bold">${r.new_packet_mark}</span>`;
|
|
|
|
|
+ else if (r.new_mss) markVal = `<span class="text-sky-300 font-mono font-bold">mss:${r.new_mss}</span>`;
|
|
|
|
|
+ else if (r.new_dscp) markVal = `<span class="text-purple-300 font-mono font-bold">dscp:${r.new_dscp}</span>`;
|
|
|
|
|
+ else if (r.new_ttl) markVal = `<span class="text-blue-300 font-mono font-bold">ttl:${r.new_ttl}</span>`;
|
|
|
|
|
+ else if (r.new_priority) markVal = `<span class="text-indigo-300 font-mono font-bold">prio:${r.new_priority}</span>`;
|
|
|
|
|
+ else if (r.route) markVal = `<span class="text-orange-300 font-mono font-bold">route:${r.route}</span>`;
|
|
|
|
|
+ else if (r.sniff_target) markVal = `<span class="text-pink-300 font-mono font-bold">sniff:${r.sniff_target}</span>`;
|
|
|
|
|
+ else if (r.action === 'jump') markVal = `<span class="text-yellow-300 font-mono font-bold">→ ${r.jump_target || '-'}</span>`;
|
|
|
|
|
+ else if (r.action.includes('address-list') || r.action.includes('address list')) markVal = `<span class="text-emerald-300 font-mono font-bold">→ ${r.address_list || '-'}</span>`;
|
|
|
|
|
+ else if (r.action === 'log') markVal = `<span class="text-slate-400 font-mono font-bold">${r.log_prefix || 'log'}</span>`;
|
|
|
|
|
|
|
|
tr.innerHTML = `
|
|
tr.innerHTML = `
|
|
|
<td class="py-2.5 px-3 text-center text-slate-500 font-bold">${r.order || idx + 1}</td>
|
|
<td class="py-2.5 px-3 text-center text-slate-500 font-bold">${r.order || idx + 1}</td>
|
|
@@ -4086,7 +4168,7 @@ function renderMangleRules() {
|
|
|
<td class="py-2.5 px-3 text-slate-300">${formatTarget(r.src_address, r.src_address_list, r.src_geoip)}</td>
|
|
<td class="py-2.5 px-3 text-slate-300">${formatTarget(r.src_address, r.src_address_list, r.src_geoip)}</td>
|
|
|
<td class="py-2.5 px-3 text-slate-300">${formatTarget(r.dst_address, r.dst_address_list, r.dst_geoip)}</td>
|
|
<td class="py-2.5 px-3 text-slate-300">${formatTarget(r.dst_address, r.dst_address_list, r.dst_geoip)}</td>
|
|
|
<td class="py-2.5 px-3">${renderActionBadge(r.action)}</td>
|
|
<td class="py-2.5 px-3">${renderActionBadge(r.action)}</td>
|
|
|
- <td class="py-2.5 px-3 font-mono font-bold text-cyan-300">${markVal || '-'}</td>
|
|
|
|
|
|
|
+ <td class="py-2.5 px-3 font-mono text-xs">${markVal}</td>
|
|
|
<td class="py-2.5 px-3 text-center">${r.passthrough ? '<span class="text-emerald-400">yes</span>' : '<span class="text-slate-500">no</span>'}</td>
|
|
<td class="py-2.5 px-3 text-center">${r.passthrough ? '<span class="text-emerald-400">yes</span>' : '<span class="text-slate-500">no</span>'}</td>
|
|
|
<td class="py-2.5 px-3 text-[11px] text-slate-400">
|
|
<td class="py-2.5 px-3 text-[11px] text-slate-400">
|
|
|
<span class="text-slate-300">${(r.packets || 0).toLocaleString()}p</span> /
|
|
<span class="text-slate-300">${(r.packets || 0).toLocaleString()}p</span> /
|
|
@@ -4213,10 +4295,10 @@ function toggleMaximizeMangleModal() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function toggleMangleActionFields() {
|
|
function toggleMangleActionFields() {
|
|
|
- const act = document.getElementById('mangle-modal-action')?.value || 'accept';
|
|
|
|
|
|
|
+ const act = document.getElementById('mangle-modal-action')?.value || 'mark-connection';
|
|
|
|
|
|
|
|
// Hide all dynamic rows first
|
|
// Hide all dynamic rows first
|
|
|
- ['newconnmark', 'newroutingmark', 'newpktmark', 'newmss', 'newdscp', 'newttl', 'passthrough'].forEach(id => {
|
|
|
|
|
|
|
+ ['newconnmark', 'newroutingmark', 'newpktmark', 'newmss', 'newdscp', 'newttl', 'newpriority', 'route', 'sniff', 'passthrough'].forEach(id => {
|
|
|
const el = document.getElementById(`mangle-row-${id}`);
|
|
const el = document.getElementById(`mangle-row-${id}`);
|
|
|
if (el) el.classList.add('hidden');
|
|
if (el) el.classList.add('hidden');
|
|
|
});
|
|
});
|
|
@@ -4244,11 +4326,33 @@ function toggleMangleActionFields() {
|
|
|
} else if (act === 'change-ttl') {
|
|
} else if (act === 'change-ttl') {
|
|
|
document.getElementById('mangle-row-newttl')?.classList.remove('hidden');
|
|
document.getElementById('mangle-row-newttl')?.classList.remove('hidden');
|
|
|
document.getElementById('mangle-row-passthrough')?.classList.remove('hidden');
|
|
document.getElementById('mangle-row-passthrough')?.classList.remove('hidden');
|
|
|
|
|
+ } else if (act === 'set-priority') {
|
|
|
|
|
+ document.getElementById('mangle-row-newpriority')?.classList.remove('hidden');
|
|
|
|
|
+ document.getElementById('mangle-row-passthrough')?.classList.remove('hidden');
|
|
|
|
|
+ } else if (act === 'route') {
|
|
|
|
|
+ document.getElementById('mangle-row-route')?.classList.remove('hidden');
|
|
|
|
|
+ document.getElementById('mangle-row-passthrough')?.classList.remove('hidden');
|
|
|
|
|
+ } else if (act === 'sniff-pc' || act === 'sniff-tzsp') {
|
|
|
|
|
+ document.getElementById('mangle-row-sniff')?.classList.remove('hidden');
|
|
|
|
|
+ document.getElementById('mangle-row-passthrough')?.classList.remove('hidden');
|
|
|
|
|
+ } else if (act === 'clear-df' || act === 'strip-ipv4-options') {
|
|
|
|
|
+ document.getElementById('mangle-row-passthrough')?.classList.remove('hidden');
|
|
|
} else if (act === 'jump') {
|
|
} else if (act === 'jump') {
|
|
|
if (jumpBox) jumpBox.classList.remove('hidden');
|
|
if (jumpBox) jumpBox.classList.remove('hidden');
|
|
|
} else if (act.includes('address-list') || act.includes('address list')) {
|
|
} else if (act.includes('address-list') || act.includes('address list')) {
|
|
|
if (addrBox) addrBox.classList.remove('hidden');
|
|
if (addrBox) addrBox.classList.remove('hidden');
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if (act === 'log') {
|
|
|
|
|
+ const logEl = document.getElementById('mangle-modal-log');
|
|
|
|
|
+ if (logEl) logEl.checked = true;
|
|
|
|
|
+ toggleMangleField('logprefix', true);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function toggleMangleLogPrefix() {
|
|
|
|
|
+ const isLog = document.getElementById('mangle-modal-log')?.checked;
|
|
|
|
|
+ toggleMangleField('logprefix', !!isLog);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const allMangleFieldKeys = [
|
|
const allMangleFieldKeys = [
|
|
@@ -4271,7 +4375,7 @@ function openAddMangleModal() {
|
|
|
document.getElementById('mangle-modal-enabled').checked = true;
|
|
document.getElementById('mangle-modal-enabled').checked = true;
|
|
|
document.getElementById('mangle-modal-comment').value = '';
|
|
document.getElementById('mangle-modal-comment').value = '';
|
|
|
document.getElementById('mangle-modal-chain').value = 'prerouting';
|
|
document.getElementById('mangle-modal-chain').value = 'prerouting';
|
|
|
- document.getElementById('mangle-modal-action').value = 'accept';
|
|
|
|
|
|
|
+ document.getElementById('mangle-modal-action').value = 'mark-connection';
|
|
|
|
|
|
|
|
if (document.getElementById('mangle-modal-newconnmark')) document.getElementById('mangle-modal-newconnmark').value = '';
|
|
if (document.getElementById('mangle-modal-newconnmark')) document.getElementById('mangle-modal-newconnmark').value = '';
|
|
|
if (document.getElementById('mangle-modal-newroutingmark')) document.getElementById('mangle-modal-newroutingmark').value = '';
|
|
if (document.getElementById('mangle-modal-newroutingmark')) document.getElementById('mangle-modal-newroutingmark').value = '';
|
|
@@ -4279,6 +4383,12 @@ function openAddMangleModal() {
|
|
|
if (document.getElementById('mangle-modal-newmss')) document.getElementById('mangle-modal-newmss').value = '';
|
|
if (document.getElementById('mangle-modal-newmss')) document.getElementById('mangle-modal-newmss').value = '';
|
|
|
if (document.getElementById('mangle-modal-newdscp')) document.getElementById('mangle-modal-newdscp').value = '';
|
|
if (document.getElementById('mangle-modal-newdscp')) document.getElementById('mangle-modal-newdscp').value = '';
|
|
|
if (document.getElementById('mangle-modal-newttl')) document.getElementById('mangle-modal-newttl').value = '';
|
|
if (document.getElementById('mangle-modal-newttl')) document.getElementById('mangle-modal-newttl').value = '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-newpriority')) document.getElementById('mangle-modal-newpriority').value = '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-route')) document.getElementById('mangle-modal-route').value = '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-sniff')) document.getElementById('mangle-modal-sniff').value = '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-jumptarget')) document.getElementById('mangle-modal-jumptarget').value = '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-action-addrlist')) document.getElementById('mangle-modal-action-addrlist').value = '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-action-timeout')) document.getElementById('mangle-modal-action-timeout').value = '';
|
|
|
if (document.getElementById('mangle-modal-passthrough')) document.getElementById('mangle-modal-passthrough').checked = true;
|
|
if (document.getElementById('mangle-modal-passthrough')) document.getElementById('mangle-modal-passthrough').checked = true;
|
|
|
if (document.getElementById('mangle-modal-log')) document.getElementById('mangle-modal-log').checked = false;
|
|
if (document.getElementById('mangle-modal-log')) document.getElementById('mangle-modal-log').checked = false;
|
|
|
|
|
|
|
@@ -4307,7 +4417,7 @@ function openEditMangleModal(id) {
|
|
|
document.getElementById('mangle-modal-enabled').checked = !r.disabled;
|
|
document.getElementById('mangle-modal-enabled').checked = !r.disabled;
|
|
|
document.getElementById('mangle-modal-comment').value = r.comment || '';
|
|
document.getElementById('mangle-modal-comment').value = r.comment || '';
|
|
|
document.getElementById('mangle-modal-chain').value = r.chain || 'prerouting';
|
|
document.getElementById('mangle-modal-chain').value = r.chain || 'prerouting';
|
|
|
- document.getElementById('mangle-modal-action').value = r.action || 'accept';
|
|
|
|
|
|
|
+ document.getElementById('mangle-modal-action').value = r.action || 'mark-connection';
|
|
|
|
|
|
|
|
if (document.getElementById('mangle-modal-newconnmark')) document.getElementById('mangle-modal-newconnmark').value = r.new_connection_mark || '';
|
|
if (document.getElementById('mangle-modal-newconnmark')) document.getElementById('mangle-modal-newconnmark').value = r.new_connection_mark || '';
|
|
|
if (document.getElementById('mangle-modal-newroutingmark')) document.getElementById('mangle-modal-newroutingmark').value = r.new_routing_mark || '';
|
|
if (document.getElementById('mangle-modal-newroutingmark')) document.getElementById('mangle-modal-newroutingmark').value = r.new_routing_mark || '';
|
|
@@ -4315,6 +4425,12 @@ function openEditMangleModal(id) {
|
|
|
if (document.getElementById('mangle-modal-newmss')) document.getElementById('mangle-modal-newmss').value = r.new_mss || '';
|
|
if (document.getElementById('mangle-modal-newmss')) document.getElementById('mangle-modal-newmss').value = r.new_mss || '';
|
|
|
if (document.getElementById('mangle-modal-newdscp')) document.getElementById('mangle-modal-newdscp').value = r.new_dscp != null ? r.new_dscp : '';
|
|
if (document.getElementById('mangle-modal-newdscp')) document.getElementById('mangle-modal-newdscp').value = r.new_dscp != null ? r.new_dscp : '';
|
|
|
if (document.getElementById('mangle-modal-newttl')) document.getElementById('mangle-modal-newttl').value = r.new_ttl || '';
|
|
if (document.getElementById('mangle-modal-newttl')) document.getElementById('mangle-modal-newttl').value = r.new_ttl || '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-newpriority')) document.getElementById('mangle-modal-newpriority').value = r.new_priority || '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-route')) document.getElementById('mangle-modal-route').value = r.route || '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-sniff')) document.getElementById('mangle-modal-sniff').value = r.sniff_target || '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-jumptarget')) document.getElementById('mangle-modal-jumptarget').value = r.jump_target || '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-action-addrlist')) document.getElementById('mangle-modal-action-addrlist').value = r.address_list || '';
|
|
|
|
|
+ if (document.getElementById('mangle-modal-action-timeout')) document.getElementById('mangle-modal-action-timeout').value = r.address_list_timeout || '';
|
|
|
if (document.getElementById('mangle-modal-passthrough')) document.getElementById('mangle-modal-passthrough').checked = r.passthrough ?? true;
|
|
if (document.getElementById('mangle-modal-passthrough')) document.getElementById('mangle-modal-passthrough').checked = r.passthrough ?? true;
|
|
|
if (document.getElementById('mangle-modal-log')) document.getElementById('mangle-modal-log').checked = !!r.log;
|
|
if (document.getElementById('mangle-modal-log')) document.getElementById('mangle-modal-log').checked = !!r.log;
|
|
|
|
|
|
|
@@ -4580,6 +4696,9 @@ async function applyMangleRule(closeAfter = false) {
|
|
|
new_mss: action === 'change-mss' ? (document.getElementById('mangle-modal-newmss')?.value.trim() || '') : '',
|
|
new_mss: action === 'change-mss' ? (document.getElementById('mangle-modal-newmss')?.value.trim() || '') : '',
|
|
|
new_dscp: action === 'change-dscp' ? parseInt(document.getElementById('mangle-modal-newdscp')?.value || '0', 10) : 0,
|
|
new_dscp: action === 'change-dscp' ? parseInt(document.getElementById('mangle-modal-newdscp')?.value || '0', 10) : 0,
|
|
|
new_ttl: action === 'change-ttl' ? (document.getElementById('mangle-modal-newttl')?.value.trim() || '') : '',
|
|
new_ttl: action === 'change-ttl' ? (document.getElementById('mangle-modal-newttl')?.value.trim() || '') : '',
|
|
|
|
|
+ new_priority: action === 'set-priority' ? (document.getElementById('mangle-modal-newpriority')?.value.trim() || '') : '',
|
|
|
|
|
+ route: action === 'route' ? (document.getElementById('mangle-modal-route')?.value.trim() || '') : '',
|
|
|
|
|
+ sniff_target: (action === 'sniff-pc' || action === 'sniff-tzsp') ? (document.getElementById('mangle-modal-sniff')?.value.trim() || '') : '',
|
|
|
passthrough: document.getElementById('mangle-modal-passthrough')?.checked ?? true,
|
|
passthrough: document.getElementById('mangle-modal-passthrough')?.checked ?? true,
|
|
|
jump_target: action === 'jump' ? (document.getElementById('mangle-modal-jumptarget')?.value || '') : '',
|
|
jump_target: action === 'jump' ? (document.getElementById('mangle-modal-jumptarget')?.value || '') : '',
|
|
|
address_list: action.includes('address') ? (document.getElementById('mangle-modal-action-addrlist')?.value || '') : '',
|
|
address_list: action.includes('address') ? (document.getElementById('mangle-modal-action-addrlist')?.value || '') : '',
|
|
@@ -4780,6 +4899,7 @@ function renderAddressLists() {
|
|
|
`;
|
|
`;
|
|
|
tbody.appendChild(tr);
|
|
tbody.appendChild(tr);
|
|
|
});
|
|
});
|
|
|
|
|
+ populateCommonAddrListDatalist();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function openAddAddrListModal() {
|
|
function openAddAddrListModal() {
|