Skip to content

Commit 99358ae

Browse files
committed
wip ti-mo please add this support code
Signed-off-by: Simone Magnani <[email protected]>
1 parent 04ddcfb commit 99358ae

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

collection.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error
189189
// Returns an error if any of the eBPF objects can't be found, or
190190
// if the same MapSpec or ProgramSpec is assigned multiple times.
191191
func (cs *CollectionSpec) Assign(to interface{}) error {
192-
// Assign() only supports assigning ProgramSpecs and MapSpecs,
193-
// so doesn't load any resources into the kernel.
192+
// Assign() only supports assigning ProgramSpecs, MapSpecs
193+
// and VariableSpecs, so doesn't load any resources into the kernel.
194194
getValue := func(typ reflect.Type, name string) (interface{}, error) {
195195
switch typ {
196196

@@ -206,6 +206,12 @@ func (cs *CollectionSpec) Assign(to interface{}) error {
206206
}
207207
return nil, fmt.Errorf("missing map %q", name)
208208

209+
case reflect.TypeOf((*VariableSpec)(nil)):
210+
if m := cs.Variables[name]; m != nil {
211+
return m, nil
212+
}
213+
return nil, fmt.Errorf("missing variable %q", name)
214+
209215
default:
210216
return nil, fmt.Errorf("unsupported type %s", typ)
211217
}
@@ -269,6 +275,11 @@ func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions)
269275
return loader.loadVariable(name)
270276

271277
default:
278+
if typ.Kind() == reflect.Pointer && typ.Elem().ConvertibleTo(reflect.TypeOf((*Variable)(nil)).Elem()) {
279+
assignedVars[name] = true
280+
return loader.loadVariable(name)
281+
}
282+
272283
return nil, fmt.Errorf("unsupported type %s", typ)
273284
}
274285
}
@@ -752,8 +763,8 @@ func (coll *Collection) Assign(to interface{}) error {
752763
assignedProgs := make(map[string]bool)
753764
assignedVars := make(map[string]bool)
754765

755-
// Assign() only transfers already-loaded Maps and Programs. No extra
756-
// loading is done.
766+
// Assign() only transfers already-loaded Maps, Programs and Variablees.
767+
// No extra loading is done.
757768
getValue := func(typ reflect.Type, name string) (interface{}, error) {
758769
switch typ {
759770

@@ -779,6 +790,15 @@ func (coll *Collection) Assign(to interface{}) error {
779790
return nil, fmt.Errorf("missing variable %q", name)
780791

781792
default:
793+
if typ.Kind() == reflect.Pointer && typ.Elem().ConvertibleTo(reflect.TypeOf((*Variable)(nil)).Elem()) {
794+
assignedVars[name] = true
795+
if v := coll.Variables[name]; v != nil {
796+
assignedVars[name] = true
797+
return v, nil
798+
}
799+
return nil, fmt.Errorf("missing variable %q", name)
800+
}
801+
782802
return nil, fmt.Errorf("unsupported type %s", typ)
783803
}
784804
}

variable.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ebpf
22

33
import (
44
"fmt"
5+
"sync/atomic"
56

67
"github.com/cilium/ebpf/btf"
78
"github.com/cilium/ebpf/internal/sysenc"
@@ -177,3 +178,37 @@ func (v *Variable) Get(out any) error {
177178

178179
return nil
179180
}
181+
182+
func (v *Variable) AtomicUint32() (r *Uint32, err error) {
183+
if err := bounds(v.mm, v.offset, atomic.Uint32{}); err != nil {
184+
return nil, fmt.Errorf("offset out of range: %w", err)
185+
}
186+
return &Uint32{reinterp[*atomic.Uint32](&v.mm.b[v.offset]), v.mm}, nil
187+
}
188+
189+
// Uint64 returns a pointer to an atomic uint64 in the memory-mapped region at
190+
// offset off.
191+
func (v *Variable) AtomicUint64() (r *Uint64, err error) {
192+
if err := bounds(v.mm, v.offset, atomic.Uint64{}); err != nil {
193+
return nil, fmt.Errorf("offset out of range: %w", err)
194+
}
195+
return &Uint64{reinterp[*atomic.Uint64](&v.mm.b[v.offset]), v.mm}, nil
196+
}
197+
198+
// Int32 returns a pointer to an atomic int32 in the memory-mapped region at
199+
// offset off.
200+
func (v *Variable) AtomicInt32() (r *Int32, err error) {
201+
if err := bounds(v.mm, v.offset, atomic.Int32{}); err != nil {
202+
return nil, fmt.Errorf("offset out of range: %w", err)
203+
}
204+
return &Int32{reinterp[*atomic.Int32](&v.mm.b[v.offset]), v.mm}, nil
205+
}
206+
207+
// Int64 returns a pointer to an atomic int64 in the memory-mapped region at
208+
// offset off.
209+
func (v *Variable) AtomicInt64() (r *Int64, err error) {
210+
if err := bounds(v.mm, v.offset, atomic.Int64{}); err != nil {
211+
return nil, fmt.Errorf("offset out of range: %w", err)
212+
}
213+
return &Int64{reinterp[*atomic.Int64](&v.mm.b[v.offset]), v.mm}, nil
214+
}

0 commit comments

Comments
 (0)