routing

package
v0.2.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 30, 2026 License: GPL-3.0 Imports: 9 Imported by: 0

Documentation

Overview

Package routing owns Linux policy routing for sending selected traffic through an already-created VPN TUN interface.

The package never installs VPN defaults into the system main table. Instead it compiles desired routes into package-owned VPN and safe-bypass tables, and reconciles only policy rules inside the caller-provided priority block. This keeps rollback narrow: all package-owned rules can be removed by priority and all package-owned tables can be flushed without touching host routing state.

Index

Constants

View Source
const (
	// DefaultAppBypassMark is the suggested mark for VPN transport sockets
	// that must route directly through main and never loop back into the VPN.
	DefaultAppBypassMark uint32 = 0xeb9f0001

	// DefaultMarkMask matches all 32 bits of a packet mark.
	DefaultMarkMask uint32 = 0xffffffff

	// DefaultPrioritySpan is the minimum practical size of a package-owned
	// priority block. The compiler currently uses fewer slots, but keeping a
	// larger span leaves room for future selectors without changing callers.
	DefaultPrioritySpan = 32

	// DefaultPriorityBase is intentionally well after kernel priority 0 and
	// before the normal main/default rule priorities.
	DefaultPriorityBase = 10000

	// Suggested table IDs for callers that do not have their own allocation.
	DefaultVPNTable  = 51820
	DefaultSafeTable = 51821
)

Variables

View Source
var (
	ErrInvalidConfig   = errors.New("routing: invalid config")
	ErrTUNLinkNotFound = errors.New("routing: TUN link not found")
)
View Source
var (
	ErrApplyFailedGuardActive = errors.New(
		"routing: apply failed with transition guard active",
	)
	ErrRollbackIncomplete = errors.New("routing: rollback incomplete")
)
View Source
var BothFamilies = FamilySet{IPv4: true, IPv6: true}

BothFamilies enables IPv4 and IPv6.

Functions

func ValidateConfig

func ValidateConfig(config Config) error

ValidateConfig checks whether config can be compiled or applied.

Types

type Config

type Config struct {
	TUNIndex int

	VPNTable  int
	SafeTable int

	PriorityBase int
	PrioritySpan int

	AppBypassMark uint32
	AppBypassMask uint32
	UserMark      uint32
	UserMarkMask  uint32

	Mode       Mode
	Strictness Strictness
	Families   FamilySet
}

Config describes the routing state a Manager should enforce.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a conservative starting point. Callers must still set TUNIndex and should set UserMark to the value used by their packet marker.

type DesiredState

type DesiredState struct {
	Config     Config
	Rules      []Rule
	VPNRoutes  []Route
	SafeRoutes []Route
}

DesiredState is the complete result of compiling a validated config.

func CompileDesiredState

func CompileDesiredState(
	config Config,
	snapshot Snapshot,
) (DesiredState, error)

CompileDesiredState turns a validated config and main-table snapshot into a deterministic desired state. It does not mutate kernel state.

type FamilySet

type FamilySet struct {
	IPv4 bool
	IPv6 bool
}

FamilySet selects which IP families the manager owns.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager reconciles package-owned Linux routes and rules.

func NewManager

func NewManager() (*Manager, error)

NewManager creates a Manager backed by a real netlink handle.

func (*Manager) Apply

func (m *Manager) Apply(config Config) error

Apply validates config, snapshots main, compiles desired routing state, and reconciles the package-owned priority block and tables.

func (*Manager) Close

func (m *Manager) Close() error

Close closes the underlying netlink handle. It does not rollback state.

func (*Manager) Refresh

func (m *Manager) Refresh() error

Refresh rebuilds the safe table from the current main table while preserving currently applied rules and VPN routes.

func (*Manager) Rollback

func (m *Manager) Rollback(config Config) error

Rollback removes all package-owned rules and flushes package-owned tables. It is idempotent and does not require knowing the active mode.

func (*Manager) Status

func (m *Manager) Status() (DesiredState, bool)

Status returns the last successfully applied desired state.

type Mode

type Mode int

Mode selects whether the user mark means exclude-from-VPN or include-in-VPN.

const (
	ModeExclude Mode = iota
	ModeInclude
)

func (Mode) String

func (m Mode) String() string

type Nexthop

type Nexthop struct {
	LinkIndex int
	Gateway   netip.Addr
	Flags     int
}

Nexthop is the normalized subset of multipath nexthop fields relevant to safety decisions and route replay.

type Route

type Route struct {
	Family    int
	Table     int
	Dst       netip.Prefix
	Gateway   netip.Addr
	LinkIndex int
	Priority  int
	Scope     int
	Flags     int
	Type      RouteType
	Multipath []Nexthop
}

Route is the package's normalized route model.

type RouteType

type RouteType int

RouteType describes the subset of kernel route types the classifier accepts.

const (
	RouteTypeUnicast RouteType = iota
	RouteTypeUnsupported
)

type Rule

type Rule struct {
	Family   int
	Priority int
	Action   RuleAction
	Table    int
	Mark     uint32
	Mask     uint32
}

Rule is the package's normalized policy-rule model.

func TransitionGuardRules

func TransitionGuardRules(config Config) ([]Rule, error)

TransitionGuardRules returns the temporary fail-closed guards for config.

type RuleAction

type RuleAction int

RuleAction is the operation performed by a policy rule.

const (
	RuleLookup RuleAction = iota
	RuleUnreachable
)

type SafeClassification

type SafeClassification int

SafeClassification is the route classifier result.

const (
	RouteIgnored SafeClassification = iota
	RouteSafe
	RouteUnsafe
)

func ClassifySafeRoute

func ClassifySafeRoute(route Route, tunIndex int) SafeClassification

ClassifySafeRoute classifies a main-table route for possible replay into the safe table. Unsafe routes are excluded because allowing them would create a direct leak path around the VPN.

type Snapshot

type Snapshot struct {
	MainRoutes []Route
}

Snapshot contains the direct host routing view copied from main.

type Strictness

type Strictness int

Strictness controls whether destination-based safe direct routes are allowed.

const (
	Strict Strictness = iota
	NonStrict
)

func (Strictness) String

func (s Strictness) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL