11package bpfprogram
22
33import (
4- "fmt"
54 "log"
65 "os"
76 "path/filepath"
@@ -10,6 +9,7 @@ import (
109 blockservice "github.com/Azure/azure-container-networking/bpf-prog/block-iptables/pkg/blockservice"
1110 "github.com/cilium/ebpf"
1211 "github.com/cilium/ebpf/link"
12+ "github.com/pkg/errors"
1313)
1414
1515const (
@@ -19,6 +19,8 @@ const (
1919 EventCounterMapName = "event_counter"
2020)
2121
22+ var ErrEventCounterMapNotLoaded = errors .New ("event counter map not loaded" )
23+
2224// Program implements the Manager interface for real BPF program operations.
2325type Program struct {
2426 objs * blockservice.BlockIptablesObjects
@@ -35,21 +37,21 @@ func NewProgram() Attacher {
3537func (p * Program ) CreatePinPath () error {
3638 // Ensure the BPF map pin directory exists with correct permissions (drwxr-xr-x)
3739 if err := os .MkdirAll (BPFMapPinPath , 0o755 ); err != nil {
38- return fmt . Errorf ( "failed to create BPF map pin directory: %w" , err )
40+ return errors . Wrap ( err , "failed to create BPF map pin directory" )
3941 }
4042 return nil
4143}
4244
4345// pinEventCounterMap pins the event counter map to the filesystem
4446func (p * Program ) pinEventCounterMap () error {
4547 if p .objs == nil || p .objs .EventCounter == nil {
46- return fmt . Errorf ( "event counter map not loaded" )
48+ return ErrEventCounterMapNotLoaded
4749 }
4850
4951 pinPath := filepath .Join (BPFMapPinPath , EventCounterMapName )
5052
5153 if err := p .objs .EventCounter .Pin (pinPath ); err != nil {
52- return fmt . Errorf ( "failed to pin event counter map to %s: %w " , pinPath , err )
54+ return errors . Wrapf ( err , "failed to pin event counter map to %s" , pinPath )
5355 }
5456
5557 log .Printf ("Event counter map pinned to %s" , pinPath )
@@ -61,24 +63,23 @@ func (p *Program) unpinEventCounterMap() error {
6163 pinPath := filepath .Join (BPFMapPinPath , EventCounterMapName )
6264
6365 if err := os .Remove (pinPath ); err != nil && ! os .IsNotExist (err ) {
64- log . Printf ( "Warning: failed to remove pinned map %s: %v " , pinPath , err )
66+ return errors . Wrapf ( err , " failed to remove pinned map %s" , pinPath )
6567 } else {
6668 log .Printf ("Event counter map unpinned from %s" , pinPath )
6769 }
6870
6971 return nil
7072}
7173
72- func getHostNetnsInode () (uint32 , error ) {
74+ func getHostNetnsInode () (uint64 , error ) {
7375 var stat syscall.Stat_t
7476 err := syscall .Stat ("/proc/self/ns/net" , & stat )
7577 if err != nil {
76- return 0 , fmt . Errorf ( "failed to stat /proc/self/ns/net: %w" , err )
78+ return 0 , errors . Wrap ( err , "failed to stat /proc/self/ns/net" )
7779 }
7880
79- inode := uint32 (stat .Ino )
80- log .Printf ("Host network namespace inode: %d" , inode )
81- return inode , nil
81+ log .Printf ("Host network namespace inode: %d" , stat .Ino )
82+ return stat .Ino , nil
8283}
8384
8485// Attach attaches the BPF program to LSM hooks.
@@ -93,25 +94,25 @@ func (p *Program) Attach() error {
9394 // Get the host network namespace inode
9495 hostNetnsInode , err := getHostNetnsInode ()
9596 if err != nil {
96- return fmt . Errorf ( "failed to get host network namespace inode: %w" , err )
97+ return errors . Wrap ( err , "failed to get host network namespace inode" )
9798 }
9899
99- if err : = p .CreatePinPath (); err != nil {
100- return fmt . Errorf ( "failed to create BPF map pin directory: %w" , err )
100+ if err = p .CreatePinPath (); err != nil {
101+ return errors . Wrap ( err , "failed to create BPF map pin directory" )
101102 }
102103
103104 // Load BPF objects with the host namespace inode set
104105 spec , err := blockservice .LoadBlockIptables ()
105106 if err != nil {
106- return fmt . Errorf ( "failed to load BPF spec: %w" , err )
107+ return errors . Wrap ( err , "failed to load BPF spec" )
107108 }
108109
109110 // Set the host_netns_inode variable in the BPF program before loading
110111 // Note: The C program sets it to hostNetnsInode + 1, so we do the same
111- if err : = spec .RewriteConstants (map [string ]interface {}{
112+ if err = spec .RewriteConstants (map [string ]interface {}{
112113 "host_netns_inode" : hostNetnsInode ,
113114 }); err != nil {
114- return fmt . Errorf ( "failed to rewrite constants: %w" , err )
115+ return errors . Wrap ( err , "failed to rewrite constants" )
115116 }
116117
117118 // Load the objects
@@ -122,14 +123,14 @@ func (p *Program) Attach() error {
122123 LoadPinOptions : ebpf.LoadPinOptions {},
123124 },
124125 }
125- if err : = spec .LoadAndAssign (objs , options ); err != nil {
126- return fmt . Errorf ( "failed to load BPF objects: %w" , err )
126+ if err = spec .LoadAndAssign (objs , options ); err != nil {
127+ return errors . Wrap ( err , "failed to load BPF objects" )
127128 }
128129 p .objs = objs
129130
130131 // Pin the event counter map to filesystem
131- if err : = p .pinEventCounterMap (); err != nil {
132- return fmt . Errorf ( "failed to pin event counter map: %w" , err )
132+ if err = p .pinEventCounterMap (); err != nil {
133+ return errors . Wrap ( err , "failed to pin event counter map" )
133134 }
134135
135136 // Attach LSM programs
@@ -142,7 +143,7 @@ func (p *Program) Attach() error {
142143 })
143144 if err != nil {
144145 p .objs .Close ()
145- return fmt . Errorf ( "failed to attach iptables_legacy_block LSM: %w" , err )
146+ return errors . Wrap ( err , "failed to attach iptables_legacy_block LSM" )
146147 }
147148 links = append (links , l )
148149 }
@@ -158,7 +159,7 @@ func (p *Program) Attach() error {
158159 link .Close ()
159160 }
160161 p .objs .Close ()
161- return fmt . Errorf ( "failed to attach block_nf_netlink LSM: %w" , err )
162+ return errors . Wrap ( err , "failed to attach block_nf_netlink LSM" )
162163 }
163164 links = append (links , l )
164165 }
@@ -210,5 +211,7 @@ func (p *Program) IsAttached() bool {
210211
211212// Close cleans up all resources.
212213func (p * Program ) Close () {
213- p .Detach ()
214+ if err := p .Detach (); err != nil {
215+ log .Println ("Warning: failed to detach BPF program:" , err )
216+ }
214217}
0 commit comments