abi.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package ebpf
  2. import (
  3. "github.com/pkg/errors"
  4. )
  5. // CollectionABI describes the interface of an eBPF collection.
  6. type CollectionABI struct {
  7. Maps map[string]*MapABI
  8. Programs map[string]*ProgramABI
  9. }
  10. // CheckSpec verifies that all maps and programs mentioned
  11. // in the ABI are present in the spec.
  12. func (abi *CollectionABI) CheckSpec(cs *CollectionSpec) error {
  13. for name := range abi.Maps {
  14. if cs.Maps[name] == nil {
  15. return errors.Errorf("missing map %s", name)
  16. }
  17. }
  18. for name := range abi.Programs {
  19. if cs.Programs[name] == nil {
  20. return errors.Errorf("missing program %s", name)
  21. }
  22. }
  23. return nil
  24. }
  25. // Check verifies that all items in a collection conform to this ABI.
  26. func (abi *CollectionABI) Check(coll *Collection) error {
  27. for name, mapABI := range abi.Maps {
  28. m := coll.Maps[name]
  29. if m == nil {
  30. return errors.Errorf("missing map %s", name)
  31. }
  32. if err := mapABI.Check(m); err != nil {
  33. return errors.Wrapf(err, "map %s", name)
  34. }
  35. }
  36. for name, progABI := range abi.Programs {
  37. p := coll.Programs[name]
  38. if p == nil {
  39. return errors.Errorf("missing program %s", name)
  40. }
  41. if err := progABI.Check(p); err != nil {
  42. return errors.Wrapf(err, "program %s", name)
  43. }
  44. }
  45. return nil
  46. }
  47. // MapABI describes a Map.
  48. //
  49. // Use it to assert that a Map matches what your code expects.
  50. type MapABI struct {
  51. Type MapType
  52. KeySize uint32
  53. ValueSize uint32
  54. MaxEntries uint32
  55. InnerMap *MapABI
  56. }
  57. func newMapABIFromSpec(spec *MapSpec) *MapABI {
  58. var inner *MapABI
  59. if spec.InnerMap != nil {
  60. inner = newMapABIFromSpec(spec.InnerMap)
  61. }
  62. return &MapABI{
  63. spec.Type,
  64. spec.KeySize,
  65. spec.ValueSize,
  66. spec.MaxEntries,
  67. inner,
  68. }
  69. }
  70. func newMapABIFromFd(fd *bpfFD) (*MapABI, error) {
  71. info, err := bpfGetMapInfoByFD(fd)
  72. if err != nil {
  73. return nil, err
  74. }
  75. mapType := MapType(info.mapType)
  76. if mapType == ArrayOfMaps || mapType == HashOfMaps {
  77. return nil, errors.New("can't get map info for nested maps")
  78. }
  79. return &MapABI{
  80. mapType,
  81. info.keySize,
  82. info.valueSize,
  83. info.maxEntries,
  84. nil,
  85. }, nil
  86. }
  87. // Check verifies that a Map conforms to the ABI.
  88. //
  89. // Members of ABI which have the zero value of their type are not checked.
  90. func (abi *MapABI) Check(m *Map) error {
  91. return abi.check(&m.abi)
  92. }
  93. func (abi *MapABI) check(other *MapABI) error {
  94. if abi.Type != UnspecifiedMap && other.Type != abi.Type {
  95. return errors.Errorf("expected map type %s, have %s", abi.Type, other.Type)
  96. }
  97. if err := checkUint32("key size", abi.KeySize, other.KeySize); err != nil {
  98. return err
  99. }
  100. if err := checkUint32("value size", abi.ValueSize, other.ValueSize); err != nil {
  101. return err
  102. }
  103. if err := checkUint32("max entries", abi.MaxEntries, other.MaxEntries); err != nil {
  104. return err
  105. }
  106. if abi.InnerMap == nil {
  107. if abi.Type == ArrayOfMaps || abi.Type == HashOfMaps {
  108. return errors.New("missing inner map ABI")
  109. }
  110. return nil
  111. }
  112. if other.InnerMap == nil {
  113. return errors.New("missing inner map")
  114. }
  115. return errors.Wrap(abi.InnerMap.check(other.InnerMap), "inner map")
  116. }
  117. // ProgramABI describes a Program.
  118. //
  119. // Use it to assert that a Program matches what your code expects.
  120. type ProgramABI struct {
  121. Type ProgramType
  122. }
  123. func newProgramABIFromSpec(spec *ProgramSpec) *ProgramABI {
  124. return &ProgramABI{
  125. spec.Type,
  126. }
  127. }
  128. func newProgramABIFromFd(fd *bpfFD) (*ProgramABI, error) {
  129. info, err := bpfGetProgInfoByFD(fd)
  130. if err != nil {
  131. return nil, err
  132. }
  133. return newProgramABIFromInfo(info), nil
  134. }
  135. func newProgramABIFromInfo(info *bpfProgInfo) *ProgramABI {
  136. return &ProgramABI{
  137. Type: ProgramType(info.progType),
  138. }
  139. }
  140. // Check verifies that a Program conforms to the ABI.
  141. //
  142. // Members which have the zero value of their type
  143. // are not checked.
  144. func (abi *ProgramABI) Check(prog *Program) error {
  145. if abi.Type != UnspecifiedProgram && prog.abi.Type != abi.Type {
  146. return errors.Errorf("expected program type %s, have %s", abi.Type, prog.abi.Type)
  147. }
  148. return nil
  149. }
  150. func checkUint32(name string, want, have uint32) error {
  151. if want != 0 && have != want {
  152. return errors.Errorf("expected %s to be %d, have %d", name, want, have)
  153. }
  154. return nil
  155. }