Documentation
¶
Index ¶
- Constants
- Variables
- func ParseTargets(values []string) (prefixes []netip.Prefix, 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) 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" ReasonInvalidEntry = `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.
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) (prefixes []netip.Prefix, hosts []string, star bool, rejected []compiler.RejectedTarget)
ParseTargets converts policy-authored network target strings into the IPv4 prefixes and DNS names the egress maps can hold.
- an IPv4 literal yields a /32 prefix
- an IPv4 CIDR yields that prefix, masked
- a DNS name yields one host, normalized by compiler.ParseNetworkValue
- compiler.StarTarget ("*") sets star, the default-deny sentinel, and yields neither
- IPv6 literals/CIDRs, wildcards, oversized names and empty values are returned in rejected
- Domains
Prefixes 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) 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.