...
1 package internal
2
3 import (
4 "fmt"
5 "sync"
6
7 "github.com/cilium/ebpf/internal/unix"
8 )
9
10 const (
11
12
13
14
15 MagicKernelVersion = 0xFFFFFFFE
16 )
17
18 var (
19 kernelVersion = struct {
20 once sync.Once
21 version Version
22 err error
23 }{}
24 )
25
26
27 type Version [3]uint16
28
29
30
31
32 func NewVersion(ver string) (Version, error) {
33 var major, minor, patch uint16
34 n, _ := fmt.Sscanf(ver, "%d.%d.%d", &major, &minor, &patch)
35 if n < 2 {
36 return Version{}, fmt.Errorf("invalid version: %s", ver)
37 }
38 return Version{major, minor, patch}, nil
39 }
40
41
42 func NewVersionFromCode(code uint32) Version {
43 return Version{
44 uint16(uint8(code >> 16)),
45 uint16(uint8(code >> 8)),
46 uint16(uint8(code)),
47 }
48 }
49
50 func (v Version) String() string {
51 if v[2] == 0 {
52 return fmt.Sprintf("v%d.%d", v[0], v[1])
53 }
54 return fmt.Sprintf("v%d.%d.%d", v[0], v[1], v[2])
55 }
56
57
58 func (v Version) Less(other Version) bool {
59 for i, a := range v {
60 if a == other[i] {
61 continue
62 }
63 return a < other[i]
64 }
65 return false
66 }
67
68
69 func (v Version) Unspecified() bool {
70 return v[0] == 0 && v[1] == 0 && v[2] == 0
71 }
72
73
74
75 func (v Version) Kernel() uint32 {
76
77
78
79
80 s := v[2]
81 if s > 255 {
82 s = 255
83 }
84
85
86
87 return uint32(uint8(v[0]))<<16 | uint32(uint8(v[1]))<<8 | uint32(uint8(s))
88 }
89
90
91 func KernelVersion() (Version, error) {
92 kernelVersion.once.Do(func() {
93 kernelVersion.version, kernelVersion.err = detectKernelVersion()
94 })
95
96 if kernelVersion.err != nil {
97 return Version{}, kernelVersion.err
98 }
99 return kernelVersion.version, nil
100 }
101
102
103 func detectKernelVersion() (Version, error) {
104 vc, err := vdsoVersion()
105 if err != nil {
106 return Version{}, err
107 }
108 return NewVersionFromCode(vc), nil
109 }
110
111
112
113
114
115 func KernelRelease() (string, error) {
116 var uname unix.Utsname
117 if err := unix.Uname(&uname); err != nil {
118 return "", fmt.Errorf("uname failed: %w", err)
119 }
120
121 return unix.ByteSliceToString(uname.Release[:]), nil
122 }
123
View as plain text