Documentation
¶
Index ¶
- Constants
- Variables
- func ParseTargets(values []string) (addrs []netip.Addr, hosts []string, star bool, ...)
- type EgressFilter
- func (e *EgressFilter) AddIps(pair *compiler.AllowDenyPair) ([]compiler.RejectedTarget, error)
- func (e *EgressFilter) Attach(cgPath string) ([]link.Link, error)
- func (e *EgressFilter) DeleteIps(pair *compiler.AllowDenyPair) ([]compiler.RejectedTarget, error)
- func (e *EgressFilter) FlagIdx(idx uint8) (bool, error)
- func (e *EgressFilter) ReadEventsLost() (uint64, error)
- func (e *EgressFilter) ReadIPEvents() (map[IPEventKey]uint32, error)
- func (e *EgressFilter) SeedIPEvent(addr netip.Addr, decision runtimeevent.KernelDecision, count uint32) error
- func (e *EgressFilter) SetFlagIdx(idx uint8, val bool)
- func (e *EgressFilter) SetObserve(enabled bool)
- type IPEventKey
Constants ¶
const ( DEFAULT_DENY = 1 // OBSERVE is LEARNING_MODE in the C. OBSERVE = 2 )
Flag bit indices in the BPF `flags` array map, mirroring the defines in _cprog/maps.h; the C program tests `*f & (1 << IDX)`.
const ( ReasonEmpty = "empty target value" ReasonIPv6 = "IPv6 targets are not supported: the egress BPF maps are IPv4-only" ReasonCIDRTooWide = "CIDR prefix is wider than /24: expand it into narrower prefixes, or use \"*\" for default-deny" ReasonNotAnIP = `not an IPv4 address, IPv4 CIDR, hostname or "*"` ReasonWildcard = "wildcards are not supported: list each address or fully qualified hostname, or use \"*\" for default-deny" ReasonDomainTooLong = "DNS name does not fit the 128 byte domain key: name a shorter destination" ReasonTooManyDomains = "the pod already tracks 256 distinct DNS names: reduce the number of DNS targets its policies name" )
Rejection reasons. They reach operators unchanged, through logs and policy status conditions, so they explain the remedy and not just the fault.
const MaxExpandedTargets = 256
MaxExpandedTargets bounds the number of addresses a single CIDR may expand to.
const MinCIDRPrefixBits = 24
MinCIDRPrefixBits is the narrowest (numerically smallest) IPv4 prefix length ParseTargets will expand. /24 expands to MaxExpandedTargets addresses; anything wider is rejected rather than expanded, because the deny/allow maps are plain hashes of individual /32 keys.
Variables ¶
var ErrNotLoaded = errors.New("egressfilter: bpf objects not loaded")
ErrNotLoaded is returned by map-touching methods when the BPF objects are not loaded (a filter built by a test, or a failed load).
Functions ¶
func ParseTargets ¶
func ParseTargets(values []string) (addrs []netip.Addr, hosts []string, star bool, rejected []compiler.RejectedTarget)
ParseTargets converts policy-authored network target strings into the IPv4 addresses and DNS names the egress maps can hold.
The value schema (trimming, star sentinel, IPv4/CIDR forms, DNS names, IPv6 rejection) is defined once, in compiler.ParseNetworkValue. ParseTargets is the single narrowing point on top of it: a CIDR wider than /MinCIDRPrefixBits is rejected as ReasonCIDRTooWide instead of expanded, because the deny/allow maps are plain hashes of individual /32 keys, and a DNS name whose wire encoding overflows the domain key is rejected as ReasonDomainTooLong. Admission applies neither, so it never rejects a value the runtime would accept.
- an IPv4 literal yields one address
- an IPv4 CIDR with prefix >= /24 yields every address in the prefix (network and broadcast included), at most MaxExpandedTargets
- a DNS name yields one host, normalized by compiler.ParseNetworkValue
- compiler.StarTarget ("*") sets star, the default-deny sentinel, and yields neither
- IPv6 literals/CIDRs, wider CIDRs, oversized names and empty values are returned in rejected
Addresses and hosts are de-duplicated, preserving first-seen order.
Types ¶
type EgressFilter ¶
type EgressFilter struct {
// contains filtered or unexported fields
}
func (*EgressFilter) AddIps ¶
func (e *EgressFilter) AddIps(pair *compiler.AllowDenyPair) ([]compiler.RejectedTarget, error)
AddIps programs the allow and deny targets of pair into the BPF maps. Targets ParseTargets cannot represent, and DNS names that no longer fit the pod's domain table, are returned as typed rejections and logged; err covers only map-write failures. Both may be non-empty at once.
func (*EgressFilter) Attach ¶
func (e *EgressFilter) Attach(cgPath string) ([]link.Link, error)
Attach hooks both programs onto one cgroup: the egress filter that decides, and the DNS snooper that reads answers off the ingress path so the filter can tell which addresses belong to a named domain. A half-completed attach closes what it opened, because a link the caller never receives can never be closed.
func (*EgressFilter) DeleteIps ¶
func (e *EgressFilter) DeleteIps(pair *compiler.AllowDenyPair) ([]compiler.RejectedTarget, error)
DeleteIps removes the allow and deny targets of pair from the BPF maps. Rejections are reported for symmetry with AddIps: a target that was never programmed cannot be removed either.
func (*EgressFilter) FlagIdx ¶
func (e *EgressFilter) FlagIdx(idx uint8) (bool, error)
FlagIdx reports whether bit idx is set. It panics on an out-of-range idx.
func (*EgressFilter) ReadEventsLost ¶
func (e *EgressFilter) ReadEventsLost() (uint64, error)
ReadEventsLost reports flows the kernel program could not record because ip_events was full. It shares ReadIPEvents' single caller, so statLast needs no lock of its own.
func (*EgressFilter) ReadIPEvents ¶
func (e *EgressFilter) ReadIPEvents() (map[IPEventKey]uint32, error)
ReadIPEvents reads and resets the ip_events counter map, so each poll reports a delta rather than a running total. Entries whose counter is zero are omitted.
func (*EgressFilter) SeedIPEvent ¶
func (e *EgressFilter) SeedIPEvent(addr netip.Addr, decision runtimeevent.KernelDecision, count uint32) error
SeedIPEvent writes one observation entry through the ip_events map handle. It exists for the kernel smoke test in test/e2e, which pins the key marshaling seam; production counting happens in the BPF program.
func (*EgressFilter) SetFlagIdx ¶
func (e *EgressFilter) SetFlagIdx(idx uint8, val bool)
SetFlagIdx sets or clears bit idx of the flags map. It panics on an out-of-range idx, which can only be a programming error.
func (*EgressFilter) SetObserve ¶
func (e *EgressFilter) SetObserve(enabled bool)
SetObserve turns the OBSERVE (LEARNING_MODE) flag bit on or off.
type IPEventKey ¶
type IPEventKey struct {
Addr netip.Addr
Decision runtimeevent.KernelDecision
// Domain is already resolved: the kernel's numeric id is filter-local, so
// it never leaves this package. Empty when no domain was attributed.
Domain string
}
IPEventKey identifies one observation counter: a destination address, the enforcement decision the kernel program applied to the flow, and the domain the address was attributed to.