traffic: add per-app runtime app routing via cgroup marks

This commit is contained in:
beckline
2026-02-14 16:58:30 +03:00
parent 1fec4a51da
commit 90907219dc
10 changed files with 819 additions and 7 deletions

View File

@@ -15,13 +15,15 @@ import (
)
const (
trafficRulePrefMarkDirect = 11500
trafficRulePrefMarkAppVPN = 11510
trafficRulePrefDirectSubnetStart = 11600
trafficRulePrefDirectUIDStart = 11680
trafficRulePrefVPNSubnetStart = 11720
trafficRulePrefVPNUIDStart = 11800
trafficRulePrefFull = 11900
trafficRulePrefSelective = 12000
trafficRulePrefManagedMin = 11600
trafficRulePrefManagedMin = 11500
trafficRulePrefManagedMax = 12099
trafficRulePerKindLimit = 70
trafficAutoLocalDefault = true
@@ -828,6 +830,10 @@ func applyTrafficMode(st TrafficModeState, iface string) error {
removeTrafficRulesForTable()
// EN: Ensure the policy table name exists even in direct mode so mark-based rules can be installed.
// RU: Гарантируем наличие имени policy-table даже в direct режиме, чтобы можно было ставить mark-правила.
ensureRoutesTableEntry()
needVPNTable := st.Mode != TrafficModeDirect || len(eff.VPNSubnets) > 0 || len(eff.VPNUIDs) > 0
if needVPNTable {
if err := ensureTrafficRouteBase(iface, st.AutoLocalBypass); err != nil {
@@ -839,6 +845,17 @@ func applyTrafficMode(st TrafficModeState, iface string) error {
return err
}
// EN: Mark-based per-app routing support (cgroup-based marking in nftables).
// EN: These rules are safe even when no packets are marked with MARK_APP/MARK_DIRECT.
// RU: Поддержка per-app маршрутизации по mark (cgroup-based marking в nftables).
// RU: Эти правила безопасны, если пакеты не помечаются MARK_APP/MARK_DIRECT.
if err := applyRule(trafficRulePrefMarkDirect, "fwmark", MARK_DIRECT, "lookup", "main"); err != nil {
return err
}
if err := applyRule(trafficRulePrefMarkAppVPN, "fwmark", MARK_APP, "lookup", routesTableName()); err != nil {
return err
}
switch st.Mode {
case TrafficModeFullTunnel:
if err := applyRule(trafficRulePrefFull, "lookup", routesTableName()); err != nil {