gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

syscalls.go (5928B)


      1 package ebpf
      2 
      3 import (
      4 	"bytes"
      5 	"errors"
      6 	"fmt"
      7 
      8 	"github.com/cilium/ebpf/asm"
      9 	"github.com/cilium/ebpf/internal"
     10 	"github.com/cilium/ebpf/internal/sys"
     11 	"github.com/cilium/ebpf/internal/unix"
     12 )
     13 
     14 // invalidBPFObjNameChar returns true if char may not appear in
     15 // a BPF object name.
     16 func invalidBPFObjNameChar(char rune) bool {
     17 	dotAllowed := objNameAllowsDot() == nil
     18 
     19 	switch {
     20 	case char >= 'A' && char <= 'Z':
     21 		return false
     22 	case char >= 'a' && char <= 'z':
     23 		return false
     24 	case char >= '0' && char <= '9':
     25 		return false
     26 	case dotAllowed && char == '.':
     27 		return false
     28 	case char == '_':
     29 		return false
     30 	default:
     31 		return true
     32 	}
     33 }
     34 
     35 func progLoad(insns asm.Instructions, typ ProgramType, license string) (*sys.FD, error) {
     36 	buf := bytes.NewBuffer(make([]byte, 0, insns.Size()))
     37 	if err := insns.Marshal(buf, internal.NativeEndian); err != nil {
     38 		return nil, err
     39 	}
     40 	bytecode := buf.Bytes()
     41 
     42 	return sys.ProgLoad(&sys.ProgLoadAttr{
     43 		ProgType: sys.ProgType(typ),
     44 		License:  sys.NewStringPointer(license),
     45 		Insns:    sys.NewSlicePointer(bytecode),
     46 		InsnCnt:  uint32(len(bytecode) / asm.InstructionSize),
     47 	})
     48 }
     49 
     50 var haveNestedMaps = internal.FeatureTest("nested maps", "4.12", func() error {
     51 	_, err := sys.MapCreate(&sys.MapCreateAttr{
     52 		MapType:    sys.MapType(ArrayOfMaps),
     53 		KeySize:    4,
     54 		ValueSize:  4,
     55 		MaxEntries: 1,
     56 		// Invalid file descriptor.
     57 		InnerMapFd: ^uint32(0),
     58 	})
     59 	if errors.Is(err, unix.EINVAL) {
     60 		return internal.ErrNotSupported
     61 	}
     62 	if errors.Is(err, unix.EBADF) {
     63 		return nil
     64 	}
     65 	return err
     66 })
     67 
     68 var haveMapMutabilityModifiers = internal.FeatureTest("read- and write-only maps", "5.2", func() error {
     69 	// This checks BPF_F_RDONLY_PROG and BPF_F_WRONLY_PROG. Since
     70 	// BPF_MAP_FREEZE appeared in 5.2 as well we don't do a separate check.
     71 	m, err := sys.MapCreate(&sys.MapCreateAttr{
     72 		MapType:    sys.MapType(Array),
     73 		KeySize:    4,
     74 		ValueSize:  4,
     75 		MaxEntries: 1,
     76 		MapFlags:   unix.BPF_F_RDONLY_PROG,
     77 	})
     78 	if err != nil {
     79 		return internal.ErrNotSupported
     80 	}
     81 	_ = m.Close()
     82 	return nil
     83 })
     84 
     85 var haveMmapableMaps = internal.FeatureTest("mmapable maps", "5.5", func() error {
     86 	// This checks BPF_F_MMAPABLE, which appeared in 5.5 for array maps.
     87 	m, err := sys.MapCreate(&sys.MapCreateAttr{
     88 		MapType:    sys.MapType(Array),
     89 		KeySize:    4,
     90 		ValueSize:  4,
     91 		MaxEntries: 1,
     92 		MapFlags:   unix.BPF_F_MMAPABLE,
     93 	})
     94 	if err != nil {
     95 		return internal.ErrNotSupported
     96 	}
     97 	_ = m.Close()
     98 	return nil
     99 })
    100 
    101 var haveInnerMaps = internal.FeatureTest("inner maps", "5.10", func() error {
    102 	// This checks BPF_F_INNER_MAP, which appeared in 5.10.
    103 	m, err := sys.MapCreate(&sys.MapCreateAttr{
    104 		MapType:    sys.MapType(Array),
    105 		KeySize:    4,
    106 		ValueSize:  4,
    107 		MaxEntries: 1,
    108 		MapFlags:   unix.BPF_F_INNER_MAP,
    109 	})
    110 	if err != nil {
    111 		return internal.ErrNotSupported
    112 	}
    113 	_ = m.Close()
    114 	return nil
    115 })
    116 
    117 var haveNoPreallocMaps = internal.FeatureTest("prealloc maps", "4.6", func() error {
    118 	// This checks BPF_F_NO_PREALLOC, which appeared in 4.6.
    119 	m, err := sys.MapCreate(&sys.MapCreateAttr{
    120 		MapType:    sys.MapType(Hash),
    121 		KeySize:    4,
    122 		ValueSize:  4,
    123 		MaxEntries: 1,
    124 		MapFlags:   unix.BPF_F_NO_PREALLOC,
    125 	})
    126 	if err != nil {
    127 		return internal.ErrNotSupported
    128 	}
    129 	_ = m.Close()
    130 	return nil
    131 })
    132 
    133 func wrapMapError(err error) error {
    134 	if err == nil {
    135 		return nil
    136 	}
    137 
    138 	if errors.Is(err, unix.ENOENT) {
    139 		return sys.Error(ErrKeyNotExist, unix.ENOENT)
    140 	}
    141 
    142 	if errors.Is(err, unix.EEXIST) {
    143 		return sys.Error(ErrKeyExist, unix.EEXIST)
    144 	}
    145 
    146 	if errors.Is(err, unix.ENOTSUPP) {
    147 		return sys.Error(ErrNotSupported, unix.ENOTSUPP)
    148 	}
    149 
    150 	if errors.Is(err, unix.E2BIG) {
    151 		return fmt.Errorf("key too big for map: %w", err)
    152 	}
    153 
    154 	return err
    155 }
    156 
    157 var haveObjName = internal.FeatureTest("object names", "4.15", func() error {
    158 	attr := sys.MapCreateAttr{
    159 		MapType:    sys.MapType(Array),
    160 		KeySize:    4,
    161 		ValueSize:  4,
    162 		MaxEntries: 1,
    163 		MapName:    sys.NewObjName("feature_test"),
    164 	}
    165 
    166 	fd, err := sys.MapCreate(&attr)
    167 	if err != nil {
    168 		return internal.ErrNotSupported
    169 	}
    170 
    171 	_ = fd.Close()
    172 	return nil
    173 })
    174 
    175 var objNameAllowsDot = internal.FeatureTest("dot in object names", "5.2", func() error {
    176 	if err := haveObjName(); err != nil {
    177 		return err
    178 	}
    179 
    180 	attr := sys.MapCreateAttr{
    181 		MapType:    sys.MapType(Array),
    182 		KeySize:    4,
    183 		ValueSize:  4,
    184 		MaxEntries: 1,
    185 		MapName:    sys.NewObjName(".test"),
    186 	}
    187 
    188 	fd, err := sys.MapCreate(&attr)
    189 	if err != nil {
    190 		return internal.ErrNotSupported
    191 	}
    192 
    193 	_ = fd.Close()
    194 	return nil
    195 })
    196 
    197 var haveBatchAPI = internal.FeatureTest("map batch api", "5.6", func() error {
    198 	var maxEntries uint32 = 2
    199 	attr := sys.MapCreateAttr{
    200 		MapType:    sys.MapType(Hash),
    201 		KeySize:    4,
    202 		ValueSize:  4,
    203 		MaxEntries: maxEntries,
    204 	}
    205 
    206 	fd, err := sys.MapCreate(&attr)
    207 	if err != nil {
    208 		return internal.ErrNotSupported
    209 	}
    210 	defer fd.Close()
    211 
    212 	keys := []uint32{1, 2}
    213 	values := []uint32{3, 4}
    214 	kp, _ := marshalPtr(keys, 8)
    215 	vp, _ := marshalPtr(values, 8)
    216 
    217 	err = sys.MapUpdateBatch(&sys.MapUpdateBatchAttr{
    218 		MapFd:  fd.Uint(),
    219 		Keys:   kp,
    220 		Values: vp,
    221 		Count:  maxEntries,
    222 	})
    223 	if err != nil {
    224 		return internal.ErrNotSupported
    225 	}
    226 	return nil
    227 })
    228 
    229 var haveProbeReadKernel = internal.FeatureTest("bpf_probe_read_kernel", "5.5", func() error {
    230 	insns := asm.Instructions{
    231 		asm.Mov.Reg(asm.R1, asm.R10),
    232 		asm.Add.Imm(asm.R1, -8),
    233 		asm.Mov.Imm(asm.R2, 8),
    234 		asm.Mov.Imm(asm.R3, 0),
    235 		asm.FnProbeReadKernel.Call(),
    236 		asm.Return(),
    237 	}
    238 
    239 	fd, err := progLoad(insns, Kprobe, "GPL")
    240 	if err != nil {
    241 		return internal.ErrNotSupported
    242 	}
    243 	_ = fd.Close()
    244 	return nil
    245 })
    246 
    247 var haveBPFToBPFCalls = internal.FeatureTest("bpf2bpf calls", "4.16", func() error {
    248 	insns := asm.Instructions{
    249 		asm.Call.Label("prog2").WithSymbol("prog1"),
    250 		asm.Return(),
    251 		asm.Mov.Imm(asm.R0, 0).WithSymbol("prog2"),
    252 		asm.Return(),
    253 	}
    254 
    255 	fd, err := progLoad(insns, SocketFilter, "MIT")
    256 	if errors.Is(err, unix.EINVAL) {
    257 		return internal.ErrNotSupported
    258 	}
    259 	if err != nil {
    260 		return err
    261 	}
    262 	_ = fd.Close()
    263 	return nil
    264 })