From d5892c20b425092c8b7ea0a218778cf53398cd41 Mon Sep 17 00:00:00 2001 From: Maxim Kurbatov Date: Sun, 5 Jan 2025 00:17:15 +0500 Subject: [PATCH] - Add `-fail-if-nothing-to-apply` option - Update config examples --- README.en.md | 12 ++++++++++++ README.md | 14 +++++++++++++- keenetic-pbr.example.conf | 12 ++++++++++++ lib/commands/apply.go | 17 +++++++++++++++-- lib/networking/network.go | 9 ++++++--- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/README.en.md b/README.en.md index 08a8e58..0ffda9f 100644 --- a/README.en.md +++ b/README.en.md @@ -95,6 +95,18 @@ flush_before_applying = true # Clear ipset each time before filling it table = 1001 # Routing table number (ip route table); a default gateway to the specified interface above will be added there priority = 1001 # Routing rule priority (ip rule priority); the lower the number, the higher the priority + # Advanced settings: you can specify custom iptables rules that will be applied for the ipset. + # Available variables: + # {{ipset_name}} - name of the ipset + # {{fwmark}} - fwmark + # {{table}} - number of the routing table + # {{priority}} - priority of the routing rule + # + #[[ipset.iptables_rule]] + #chain = "PREROUTING" + #table = "mangle" + #rule = ["-m", "set", "--match-set", "{{ipset_name}}", "dst,src", "-j", "MARK", "--set-mark", "{{fwmark}}"] + # List 1 (manual address entry) [[ipset.list]] name = "local" diff --git a/README.md b/README.md index 12487e0..78a98b3 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,19 @@ flush_before_applying = true # Очищать ipset каждый раз пе fwmark = 1001 # Этот fwmark будет применяться к пакетам, попавшим под критерии списков table = 1001 # Номер таблицы маршрутизации (ip route table), туда будет добавляться default gateway на интерфейс, указанный выше priority = 1001 # Приоритет правила маршрутизации (ip rule priority), чем число меньше, тем выше приоритет - + + # Настройки для продвинутых: можно указывать собственные правила iptables, которые будут применяться для ipset. + # Доступные переменные: + # {{ipset_name}} - название ipset + # {{fwmark}} - fwmark + # {{table}} - номер таблицы маршрутизации + # {{priority}} - приоритет правила маршрутизации + # + #[[ipset.iptables_rule]] + #chain = "PREROUTING" + #table = "mangle" + #rule = ["-m", "set", "--match-set", "{{ipset_name}}", "dst,src", "-j", "MARK", "--set-mark", "{{fwmark}}"] + # Список 1 (ручное перечисление адресов) [[ipset.list]] name = "local" diff --git a/keenetic-pbr.example.conf b/keenetic-pbr.example.conf index 3cf2723..a398eba 100644 --- a/keenetic-pbr.example.conf +++ b/keenetic-pbr.example.conf @@ -32,6 +32,18 @@ ip_version = 4 # iptables routing rule priority priority = 1001 + # Advanced settings: you can specify custom iptables rules that will be applied for the ipset. + # Available variables: + # {{ipset_name}} - name of the ipset + # {{fwmark}} - fwmark + # {{table}} - number of the routing table + # {{priority}} - priority of the routing rule + # + #[[ipset.iptables_rule]] + #chain = "PREROUTING" + #table = "mangle" + #rule = ["-m", "set", "--match-set", "{{ipset_name}}", "dst,src", "-j", "MARK", "--set-mark", "{{fwmark}}"] + [[ipset.list]] # Name of the domains/ips list name = "local" diff --git a/lib/commands/apply.go b/lib/commands/apply.go index ca2aec3..97859ac 100644 --- a/lib/commands/apply.go +++ b/lib/commands/apply.go @@ -5,7 +5,9 @@ import ( "fmt" "github.com/maksimkurb/keenetic-pbr/lib/config" "github.com/maksimkurb/keenetic-pbr/lib/lists" + "github.com/maksimkurb/keenetic-pbr/lib/log" "github.com/maksimkurb/keenetic-pbr/lib/networking" + "os" ) func CreateApplyCommand() *ApplyCommand { @@ -17,6 +19,7 @@ func CreateApplyCommand() *ApplyCommand { gc.fs.BoolVar(&gc.SkipIpset, "skip-ipset", false, "Skip ipset filling") gc.fs.BoolVar(&gc.SkipRouting, "skip-routing", false, "Skip ip routes and ip rules applying") gc.fs.StringVar(&gc.OnlyRoutingForInterface, "only-routing-for-interface", "", "Only apply ip routes/rules for the specified interface (if it is present in keenetic-pbr config)") + gc.fs.BoolVar(&gc.FailIfNothingToApply, "fail-if-nothing-to-apply", false, "If there is routing configuration to apply, exit with error code (5)") return gc } @@ -29,6 +32,7 @@ type ApplyCommand struct { SkipIpset bool SkipRouting bool OnlyRoutingForInterface string + FailIfNothingToApply bool } func (g *ApplyCommand) Name() string { @@ -58,15 +62,24 @@ func (g *ApplyCommand) Init(args []string, ctx *AppContext) error { } func (g *ApplyCommand) Run() error { - if !g.SkipIpset || !g.SkipDnsmasq { + if (!g.SkipIpset || !g.SkipDnsmasq) && g.OnlyRoutingForInterface == "" { if err := lists.ApplyLists(g.cfg, g.SkipDnsmasq, g.SkipIpset); err != nil { return fmt.Errorf("failed to apply configuration: %v", err) } } if !g.SkipRouting { - if err := networking.ApplyNetworkConfiguration(g.cfg, &g.OnlyRoutingForInterface); err != nil { + if appliedAtLeastOnce, err := networking.ApplyNetworkConfiguration(g.cfg, &g.OnlyRoutingForInterface); err != nil { return fmt.Errorf("failed to apply configuration: %v", err) + } else { + if !appliedAtLeastOnce { + if g.FailIfNothingToApply { + log.Warnf("Nothing to apply, exiting with error code (5)") + os.Exit(5) + } else { + log.Warnf("Nothing to apply") + } + } } } diff --git a/lib/networking/network.go b/lib/networking/network.go index 8d2b0d2..7ec56c6 100644 --- a/lib/networking/network.go +++ b/lib/networking/network.go @@ -9,9 +9,11 @@ import ( "net" ) -func ApplyNetworkConfiguration(config *config.Config, onlyRoutingForInterface *string) error { +func ApplyNetworkConfiguration(config *config.Config, onlyRoutingForInterface *string) (bool, error) { log.Infof("Applying network configuration.") + appliedAtLeastOnce := false + for _, ipset := range config.Ipset { shouldRoute := false if onlyRoutingForInterface == nil || *onlyRoutingForInterface == "" { @@ -29,12 +31,13 @@ func ApplyNetworkConfiguration(config *config.Config, onlyRoutingForInterface *s continue } + appliedAtLeastOnce = true if err := applyIpsetNetworkConfiguration(ipset, *config.General.UseKeeneticAPI); err != nil { - return err + return false, err } } - return nil + return appliedAtLeastOnce, nil } func applyIpsetNetworkConfiguration(ipset *config.IpsetConfig, useKeeneticAPI bool) error {