diff --git a/cmd/gluetun/main.go b/cmd/gluetun/main.go index 31e82144..dc36f06b 100644 --- a/cmd/gluetun/main.go +++ b/cmd/gluetun/main.go @@ -325,6 +325,11 @@ func _main(ctx context.Context, buildInfo models.BuildInformation, return err } + err = routingConf.AddLocalRules(localNetworks) + if err != nil { + return fmt.Errorf("adding local rules: %w", err) + } + const tunDevice = "/dev/net/tun" if err := tun.Check(tunDevice); err != nil { logger.Info(err.Error() + "; creating it...") diff --git a/internal/routing/local.go b/internal/routing/local.go index 0927c987..e67fa6f9 100644 --- a/internal/routing/local.go +++ b/internal/routing/local.go @@ -85,3 +85,21 @@ func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) { return localNetworks, nil } + +func (r *Routing) AddLocalRules(subnets []LocalNetwork) (err error) { + for _, net := range subnets { + // The main table is a built-in value for Linux, see "man 8 ip-route" + const mainTable = 254 + + // Local has higher priority then outbound(99) and inbound(100) as the + // local routes might be necessary to reach the outbound/inbound routes. + const localPriority = 98 + + // Main table was setup correctly by Docker, just need to add rules to use it + err = r.addIPRule(nil, net.IPNet, mainTable, localPriority) + if err != nil { + return fmt.Errorf("adding rule: %v: %w", net.IPNet, err) + } + } + return nil +}