Skip to content

Commit

Permalink
Ensure Cilium compatibility (#1535)
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelroquetto authored Jan 16, 2025
1 parent ced8575 commit 43f3609
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pkg/beyla/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ func (c *Config) Validate() error {
if !c.EBPF.TCBackend.Valid() {
return ConfigError("Invalid BEYLA_BPF_TC_BACKEND value")
}
if err := tcmanager.EnsureCiliumCompatibility(c.EBPF.TCBackend); err != nil {
return ConfigError(fmt.Sprintf("Cilium compatibility error: %s", err.Error()))
}

if c.Attributes.Kubernetes.InformersSyncTimeout == 0 {
return ConfigError("BEYLA_KUBE_INFORMERS_SYNC_TIMEOUT duration must be greater than 0s")
Expand Down
167 changes: 167 additions & 0 deletions pkg/internal/ebpf/tcmanager/cilium_support.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package tcmanager

import (
"fmt"
"log/slog"
"math"
"net"
"strings"

"github.com/cilium/ebpf"
"github.com/cilium/ebpf/link"
"github.com/vishvananda/netlink"
"golang.org/x/sys/unix"
)

const cilPrefix = "cil_"

func hasCiliumTCX() bool {
if !IsTCXSupported() {
return false
}

it := new(link.Iterator)

for it.Next() {
link := it.Take()
defer link.Close()

info, err := link.Info()

if err != nil {
continue
}

if info.Type != unix.BPF_LINK_TYPE_TCX {
continue
}

prog, err := ebpf.NewProgramFromID(info.Program)

if err != nil {
continue
}

defer prog.Close()

progInfo, err := prog.Info()

if err != nil {
continue
}

if strings.HasPrefix(progInfo.Name, cilPrefix) {
return true
}
}

return false
}

const ciliumNotFound = uint16(math.MaxUint16)

// returns the highest and lowest priorities of a cilium link,
// or ciliumNotFound if no cilium link is present
func ciliumLinkPriorities(link netlink.Link, parent uint32) (uint16, uint16) {
filters, err := netlink.FilterList(link, parent)

if err != nil {
return ciliumNotFound, 0
}

minPrio := uint16(ciliumNotFound)
maxPrio := uint16(0)

for _, filter := range filters {
bpfFilter, ok := filter.(*netlink.BpfFilter)

if !ok {
continue
}

if !strings.HasPrefix(bpfFilter.Name, cilPrefix) {
continue
}

minPrio = min(minPrio, bpfFilter.Priority)
maxPrio = max(maxPrio, bpfFilter.Priority)
}

return minPrio, maxPrio
}

func ciliumTCPriorities() (uint16, uint16) {
ifaces, err := net.Interfaces()

if err != nil {
return ciliumNotFound, 0
}

minPrio := uint16(ciliumNotFound)
maxPrio := uint16(0)

for _, iface := range ifaces {
link, err := netlink.LinkByIndex(iface.Index)

if err != nil {
continue
}

pMin, pMax := ciliumLinkPriorities(link, netlink.HANDLE_MIN_INGRESS)

minPrio = min(minPrio, pMin)
maxPrio = max(maxPrio, pMax)

pMin, pMax = ciliumLinkPriorities(link, netlink.HANDLE_MIN_EGRESS)

minPrio = min(minPrio, pMin)
maxPrio = max(maxPrio, pMax)
}

return minPrio, maxPrio
}

func normalizeBackend(backend TCBackend) TCBackend {
if backend != TCBackendAuto {
return backend
}

if IsTCXSupported() {
return TCBackendTCX
}

return TCBackendTC
}

func EnsureCiliumCompatibility(backend TCBackend) error {
// if we are trying to attach to TCX, we will always end up attaching to
// the chain head in front of cilium, so we should be good
if normalizeBackend(backend) == TCBackendTCX {
return nil
}

// we are using TC/Netlink attachment (TCBackendTC)

if hasCiliumTCX() {
return fmt.Errorf("detected Cilium TCX attachment, but Beyla has been configured to use TC")
}

minPrio, maxPrio := ciliumTCPriorities()

// no Cilium program has priority 1, we are good
if minPrio > 1 {
return nil
}

// we found Cilium programs with priority 1 and other priorities, assume
// the priority 1 programs are left-overs that we can clobber - we print a
// warning, but do not error
if maxPrio > 1 {
slog.Warn("Detected potential Cilium TC left-overs!")
return nil
}

// minPrio == maxPrio == 1 -> cilium should be reconfigured with
// bpf-filter-priority >= 2
return fmt.Errorf("detected Cilium TC with priority 1 - Cilium may clobber Beyla")
}

0 comments on commit 43f3609

Please sign in to comment.