Skip to content

Commit 8349ed9

Browse files
committed
struct_ops: fix to enforce specify a btf.Int as Key
Tests are updated to use Key instead of KeySize/ValueSize literals Signed-off-by: shun159 <[email protected]>
1 parent cfeae69 commit 8349ed9

File tree

3 files changed

+36
-19
lines changed

3 files changed

+36
-19
lines changed

collection_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -791,10 +791,9 @@ func TestStructOpsMapSpecSimpleLoadAndAssign(t *testing.T) {
791791
Name: "testmod_ops",
792792
Type: StructOpsMap,
793793
Flags: sys.BPF_F_LINK,
794-
KeySize: 4,
795-
ValueSize: 448,
796-
MaxEntries: 1,
794+
Key: &btf.Int{Size: 4},
797795
Value: &btf.Struct{Name: "bpf_struct_ops_bpf_testmod_ops"},
796+
MaxEntries: 1,
798797
Contents: []MapKV{
799798
{
800799
Key: uint32(0),

map.go

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -554,42 +554,61 @@ func (spec *MapSpec) createMap(inner *sys.FD, c *btf.Cache) (_ *Map, err error)
554554
defer handle.Close()
555555

556556
if spec.Type == StructOpsMap {
557+
if handle == nil {
558+
return nil, fmt.Errorf("struct_ops: BTF handle is not resolved")
559+
}
560+
557561
if spec.Value == nil {
558562
return nil, fmt.Errorf("struct_ops map: missing value type information")
559563
}
560564

561-
valueType, ok := btf.As[*btf.Struct](spec.Value)
565+
if spec.Key == nil {
566+
return nil, fmt.Errorf("struct_ops map: Key must be specified")
567+
}
568+
569+
keyType, ok := btf.As[*btf.Int](spec.Key)
562570
if !ok {
563-
return nil, fmt.Errorf("value must be Struct type")
571+
return nil, fmt.Errorf("key must be Int type")
564572
}
565573

566-
if spec.KeySize != 4 {
567-
return nil, fmt.Errorf("struct_ops: KeySize must be 4")
574+
// The key size of StructOps is always 4
575+
if keyType.Size != 4 {
576+
return nil, fmt.Errorf("key size must be 4")
577+
}
578+
579+
valueType, ok := btf.As[*btf.Struct](spec.Value)
580+
if !ok {
581+
return nil, fmt.Errorf("value must be Struct type")
568582
}
569583

570584
// struct_ops: resolve value type ("bpf_struct_ops_<name>") and
571585
// record kernel-specific BTF IDs / FDs needed for map creation.
572-
target := btf.Type((*btf.Struct)(nil))
573-
s, module, err := findTargetInKernel(valueType.Name, &target, c)
586+
vTarget := btf.Type((*btf.Struct)(nil))
587+
s, module, err := findTargetInKernel(valueType.Name, &vTarget, c)
574588
if err != nil {
575589
return nil, fmt.Errorf("lookup value type %q: %w", valueType.Name, err)
576590
}
577591
defer module.Close()
578592

579-
vType := target.(*btf.Struct)
580-
593+
vType := vTarget.(*btf.Struct)
581594
btfValueTypeId, err := s.TypeID(vType)
582595
if err != nil {
583596
return nil, fmt.Errorf("lookup type_id: %w", err)
584597
}
585598

586-
attr.ValueSize = spec.ValueSize
599+
attr.BtfFd = uint32(handle.FD())
587600
attr.BtfVmlinuxValueTypeId = btfValueTypeId
588-
589-
if handle == nil {
590-
return nil, fmt.Errorf("struct_ops: BTF handle is not resolved")
601+
attr.KeySize, spec.KeySize = keyType.Size, keyType.Size
602+
603+
if spec.ValueSize == 0 {
604+
attr.ValueSize, spec.ValueSize = vType.Size, vType.Size
605+
} else {
606+
// If spec.ValueSize is non-zero but does not match vtype.size, it should fail.
607+
if spec.ValueSize != vType.Size {
608+
return nil, fmt.Errorf("struct_ops: ValueSize (%d) mismatches vtype size (%d)", spec.ValueSize, vType.Size)
609+
}
610+
attr.ValueSize = spec.ValueSize
591611
}
592-
attr.BtfFd = uint32(handle.FD())
593612

594613
if module != nil {
595614
// BPF_F_VTYPE_BTF_OBJ_FD is required if the type comes from a module

struct_ops_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ func TestCreateStructOpsMapSpecSimple(t *testing.T) {
1515
Name: "testmod_ops",
1616
Type: StructOpsMap,
1717
Flags: sys.BPF_F_LINK,
18-
KeySize: 4,
19-
ValueSize: 448,
20-
MaxEntries: 1,
18+
Key: &btf.Int{Size: 4},
2119
Value: &btf.Struct{Name: "bpf_struct_ops_bpf_testmod_ops"},
20+
MaxEntries: 1,
2221
Contents: []MapKV{
2322
{
2423
Key: uint32(0),

0 commit comments

Comments
 (0)