Skip to content

Commit

Permalink
WIP2
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelroquetto committed Jan 6, 2025
1 parent 35033a4 commit f8e285a
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 35 deletions.
50 changes: 43 additions & 7 deletions pkg/internal/ebpf/tcmanager/netlinkmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func nextHandle() uint32 {
}

type netlinkProg struct {
prog *ebpf.Program
*ebpf.Program
name string
attachType AttachmentType
}
Expand Down Expand Up @@ -136,7 +136,7 @@ func (tc *netlinkManager) AddProgram(name string, prog *ebpf.Program, attachment
defer tc.mutex.Unlock()

p := &netlinkProg{
prog: prog,
Program: prog,
name: name,
attachType: attachment,
}
Expand All @@ -145,12 +145,12 @@ func (tc *netlinkManager) AddProgram(name string, prog *ebpf.Program, attachment
tc.attachProgramLocked(p)
}

func (tc *netlinkManager) RemoveProgram(_ string) {
func (tc *netlinkManager) RemoveProgram(name string) {
tc.mutex.Lock()
defer tc.mutex.Unlock()

// FIXME
// delete(tc.programs, name)
tc.detachProgramLocked(name)
tc.removeProgramLocked(name)
}

func (tc *netlinkManager) attachProgramLocked(prog *netlinkProg) {
Expand Down Expand Up @@ -181,7 +181,7 @@ func (tc *netlinkManager) attachProgramToIfaceLocked(prog *netlinkProg, iface *n

filter := &netlink.BpfFilter{
FilterAttrs: attrs,
Fd: prog.prog.FD(),
Fd: prog.FD(),
Name: prog.name,
DirectAction: true,
}
Expand All @@ -203,6 +203,42 @@ func (tc *netlinkManager) attachProgramToIfaceLocked(prog *netlinkProg, iface *n
iface.filters = append(iface.filters, filter)
}

func (tc *netlinkManager) detachProgramLocked(prog string) {
for _, iface := range tc.interfaces {
tc.detachProgramFromIfaceLocked(prog, iface)
}
}

func (tc *netlinkManager) detachProgramFromIfaceLocked(prog string, iface *netlinkIface) {
detach := func(filter *netlink.BpfFilter) {
if filter.Name != prog {
return
}

if err := netlink.FilterDel(filter); err != nil {
tc.log.Error("Failed to delete filter", "filter", prog, "error", err)
}
}

apply(iface.filters, detach)
iface.filters = removeIf(iface.filters, func(filter *netlink.BpfFilter) bool { return filter.Name == prog })
}

func (tc *netlinkManager) removeProgramLocked(name string) {
closeProgs := func(prog *netlinkProg) {
if prog.name != name {
return
}

if err := prog.Close(); err != nil {
tc.log.Error("Failed to close program", "program", prog, "error", err)
}
}

apply(tc.programs, closeProgs)
tc.programs = removeIf(tc.programs, func(prog *netlinkProg) bool { return prog.name == name })
}

func (tc *netlinkManager) onInterfaceAdded(i ifaces.Interface) {
tc.mutex.Lock()
defer tc.mutex.Unlock()
Expand Down Expand Up @@ -349,7 +385,7 @@ func ifaceHasFilters(iface *netlinkIface, parent uint32) bool {
func (tc *netlinkManager) cleanupProgsLocked() {
for _, prog := range tc.programs {
tc.log.Debug("closing tc program", "name", prog.name)
prog.prog.Close()
prog.Close()
}

tc.programs = []*netlinkProg{}
Expand Down
93 changes: 65 additions & 28 deletions pkg/internal/ebpf/tcmanager/tcxmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,32 @@ import (
)

type attachedProg struct {
prog *ebpf.Program
*ebpf.Program
attachType AttachmentType
name string
}

type ifaceLink struct {
link.Link
progName string
iface int
}

type tcxInterfaceMap map[int]ifaces.Interface
type tcxProgramsMap map[string]*attachedProg
type tcxLinksMap map[int][]link.Link

type tcxManager struct {
tcManagerBase
interfaces tcxInterfaceMap
programs tcxProgramsMap
links tcxLinksMap
programs []*attachedProg
links []*ifaceLink
}

func NewTCXManager() TCManager {
return &tcxManager{
tcManagerBase: newTCManagerBase("tcx_manager"),
interfaces: tcxInterfaceMap{},
programs: tcxProgramsMap{},
links: tcxLinksMap{},
programs: []*attachedProg{},
links: []*ifaceLink{},
}
}

Expand Down Expand Up @@ -106,8 +111,8 @@ func (tcx *tcxManager) shutdown() {

tcx.registerer = nil
tcx.interfaces = tcxInterfaceMap{}
tcx.programs = tcxProgramsMap{}
tcx.links = tcxLinksMap{}
tcx.programs = []*attachedProg{}
tcx.links = []*ifaceLink{}

tcx.log.Debug("TCX completed shutdown")
}
Expand All @@ -117,22 +122,57 @@ func (tcx *tcxManager) AddProgram(name string, prog *ebpf.Program, attachment At
defer tcx.mutex.Unlock()

p := &attachedProg{
prog: prog,
Program: prog,
attachType: attachment,
name: name,
}

tcx.programs[name] = p
tcx.attachProgramLocked(name, p)
tcx.programs = append(tcx.programs, p)
tcx.attachProgramLocked(p)
}

func (tcx *tcxManager) attachProgramLocked(prog *attachedProg) {
for iface := range tcx.interfaces {
tcx.attachProgramToIfaceLocked(prog, iface)
}
}

func (tcx *tcxManager) RemoveProgram(name string) {
delete(tcx.programs, name)
tcx.mutex.Lock()
defer tcx.mutex.Unlock()

tcx.unlinkProgramLocked(name)
tcx.removeProgramLocked(name)
}

func (tcx *tcxManager) attachProgramLocked(_ string, prog *attachedProg) {
for iface := range tcx.interfaces {
tcx.attachProgramToIfaceLocked(prog, iface)
func (tcx *tcxManager) removeProgramLocked(name string) {
closeProgs := func(prog *attachedProg) {
if prog.name != name {
return
}

if err := prog.Close(); err != nil {
tcx.log.Error("Failed to close program", "program", prog, "error", err)
}
}

apply(tcx.programs, closeProgs)
tcx.programs = removeIf(tcx.programs, func(prog *attachedProg) bool { return prog.name == name })
}

func (tcx *tcxManager) unlinkProgramLocked(name string) {
closeLinks := func(link *ifaceLink) {
if link.progName != name {
return
}

if err := link.Close(); err != nil {
tcx.log.Error("Failed to unlink program", "program", name, "error", err)
}
}

apply(tcx.links, closeLinks)
tcx.links = removeIf(tcx.links, func(link *ifaceLink) bool { return link.progName == name })
}

func (tcx *tcxManager) attachProgramToIfaceLocked(prog *attachedProg, iface int) {
Expand All @@ -143,12 +183,12 @@ func (tcx *tcxManager) attachProgramToIfaceLocked(prog *attachedProg, iface int)
attachType, err := tcxAttachType(prog.attachType)

if err != nil {
tcx.log.Error("Error attaching program", "error", err)
tcx.log.Error("Error attaching program", "program", prog.name, "error", err)
return
}

link, err := link.AttachTCX(link.TCXOptions{
Program: prog.prog,
Program: prog.Program,
Attach: attachType,
Interface: iface,
Anchor: link.Head(),
Expand All @@ -159,7 +199,7 @@ func (tcx *tcxManager) attachProgramToIfaceLocked(prog *attachedProg, iface int)
return
}

tcx.links[iface] = append(tcx.links[iface], link)
tcx.links = append(tcx.links, &ifaceLink{Link: link, progName: prog.name, iface: iface})
}

func (tcx *tcxManager) onInterfaceAdded(iface ifaces.Interface) {
Expand Down Expand Up @@ -192,17 +232,14 @@ func (tcx *tcxManager) removeInterfaceLocked(iface ifaces.Interface) {
}

func (tcx *tcxManager) closeLinksLocked(iface ifaces.Interface) {
links, ok := tcx.links[iface.Index]

if !ok {
return
}

for _, link := range links {
link.Close()
closeLinks := func(link *ifaceLink) {
if link.iface == iface.Index {
link.Close()
}
}

delete(tcx.links, iface.Index)
apply(tcx.links, closeLinks)
tcx.links = removeIf(tcx.links, func(l *ifaceLink) bool { return l.iface == iface.Index })
}

func (tcx *tcxManager) InterfaceName(ifaceIndex int) (string, bool) {
Expand Down
20 changes: 20 additions & 0 deletions pkg/internal/ebpf/tcmanager/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package tcmanager

func removeIf[T any](s []T, pred func(T) bool) []T {
i := 0

for _, v := range s {
if !pred(v) {
s[i] = v
i++
}
}

return s[:i]
}

func apply[T any](s []T, applyFunc func(T)) {
for _, v := range s {
applyFunc(v)
}
}

0 comments on commit f8e285a

Please sign in to comment.