Fix auto_redirect dropping SO_BINDTODEVICE traffic
REDIRECT in the OUTPUT chain rewrites the destination to 127.0.0.1, then ip_route_me_harder() reroutes with the socket's bound interface constraint (flowi4_oif). Since 127.0.0.1 is only reachable via lo, the routing lookup fails and the packet is silently dropped. Add a fallback routing table with `local 127.0.0.1` entries for each non-loopback interface. When the local table lookup fails due to OIF mismatch, the fallback table provides a matching RTN_LOCAL route. The kernel then overrides dev_out to loopback (route.c:2857), so the packet is delivered locally to the redirect server as intended. This fixes NetworkManager connectivity checks and other tools that use SO_BINDTODEVICE (e.g. curl --interface).
This commit is contained in:
parent
c81ce6d358
commit
caaf8469e0
3 changed files with 212 additions and 23 deletions
|
|
@ -19,29 +19,31 @@ import (
|
|||
)
|
||||
|
||||
type autoRedirect struct {
|
||||
tunOptions *Options
|
||||
ctx context.Context
|
||||
handler Handler
|
||||
logger logger.Logger
|
||||
tableName string
|
||||
networkMonitor NetworkUpdateMonitor
|
||||
networkListener *list.Element[NetworkUpdateCallback]
|
||||
interfaceFinder control.InterfaceFinder
|
||||
localAddresses []netip.Prefix
|
||||
customRedirectPortFunc func() int
|
||||
customRedirectPort int
|
||||
redirectServer *redirectServer
|
||||
enableIPv4 bool
|
||||
enableIPv6 bool
|
||||
iptablesPath string
|
||||
ip6tablesPath string
|
||||
useNFTables bool
|
||||
androidSu bool
|
||||
suPath string
|
||||
routeAddressSet *[]*netipx.IPSet
|
||||
routeExcludeAddressSet *[]*netipx.IPSet
|
||||
nfqueueHandler *nfqueueHandler
|
||||
nfqueueEnabled bool
|
||||
tunOptions *Options
|
||||
ctx context.Context
|
||||
handler Handler
|
||||
logger logger.Logger
|
||||
tableName string
|
||||
networkMonitor NetworkUpdateMonitor
|
||||
networkListener *list.Element[NetworkUpdateCallback]
|
||||
interfaceFinder control.InterfaceFinder
|
||||
localAddresses []netip.Prefix
|
||||
customRedirectPortFunc func() int
|
||||
customRedirectPort int
|
||||
redirectServer *redirectServer
|
||||
enableIPv4 bool
|
||||
enableIPv6 bool
|
||||
iptablesPath string
|
||||
ip6tablesPath string
|
||||
useNFTables bool
|
||||
androidSu bool
|
||||
suPath string
|
||||
routeAddressSet *[]*netipx.IPSet
|
||||
routeExcludeAddressSet *[]*netipx.IPSet
|
||||
nfqueueHandler *nfqueueHandler
|
||||
nfqueueEnabled bool
|
||||
redirectRouteTableIndex int
|
||||
redirectInterfaces []control.Interface
|
||||
}
|
||||
|
||||
func NewAutoRedirect(options AutoRedirectOptions) (AutoRedirect, error) {
|
||||
|
|
@ -152,6 +154,12 @@ func (r *autoRedirect) Start() error {
|
|||
}
|
||||
r.cleanupNFTables()
|
||||
err = r.setupNFTables()
|
||||
if err == nil && r.tunOptions.AutoRedirectMarkMode {
|
||||
err = r.setupRedirectRoutes()
|
||||
if err != nil {
|
||||
r.cleanupNFTables()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
r.cleanupIPTables()
|
||||
err = r.setupIPTables()
|
||||
|
|
@ -164,6 +172,7 @@ func (r *autoRedirect) Close() error {
|
|||
r.nfqueueHandler.Close()
|
||||
}
|
||||
if r.useNFTables {
|
||||
r.cleanupRedirectRoutes()
|
||||
r.cleanupNFTables()
|
||||
} else {
|
||||
r.cleanupIPTables()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue