Repository: cilium/ebpf
Pull request #1537 (2024-08-06 13:34:52)

internal/sys: add constants
internal/sys: generate constants from unnamed enums

    bpf.h defines a bunch of constants as unnamed enums. This makes them tricky
    to pull out of vmlinux BTF, so instead we rely on the internal/unix shim.
    This causes a small maintenance burden whenever we need a new flag, but more
    importantly it makes some upcoming cross platform work harder.

    Pull the constant definitions out of vmlinux BTF instead of relying on 
    package unix. Unfortunately a bunch of the flags are re-used. This is most
    noticeable for MapFlags, for which the enum in the kernel has become a bit
    of a grab bag. Instead of trying hard to wrap everything into a neat type we
    just generate untyped constants and get rid of MapFlags.

    Signed-off-by: Lorenz Bauer <lmb@isovalent.com>

internal/sys: add DEFINEd constants

    Some constants in bpf.h are defined using the C preprocessor and are 
    therefore not available in BTF. Add them manually.

    Signed-off-by: Lorenz Bauer <lmb@isovalent.com>



Patch:
diff --git a/asm/instruction.go b/asm/instruction.go
index 67cd39d..86b384c 100644
--- a/asm/instruction.go
+++ b/asm/instruction.go
@@ -12,7 +12,6 @@ import (
 	"strings"
 
 	"github.com/cilium/ebpf/internal/sys"
-	"github.com/cilium/ebpf/internal/unix"
 )
 
 // InstructionSize is the size of a BPF instruction in bytes
@@ -804,7 +803,7 @@ func (insns Instructions) Tag(bo binary.ByteOrder) (string, error) {
 			return "", fmt.Errorf("instruction %d: %w", i, err)
 		}
 	}
-	return hex.EncodeToString(h.Sum(nil)[:unix.BPF_TAG_SIZE]), nil
+	return hex.EncodeToString(h.Sum(nil)[:sys.BPF_TAG_SIZE]), nil
 }
 
 // encodeFunctionReferences populates the Offset (or Constant, depending on
diff --git a/elf_reader.go b/elf_reader.go
index 2e31a19..a1a7792 100644
--- a/elf_reader.go
+++ b/elf_reader.go
@@ -16,7 +16,6 @@ import (
 	"github.com/cilium/ebpf/btf"
 	"github.com/cilium/ebpf/internal"
 	"github.com/cilium/ebpf/internal/sys"
-	"github.com/cilium/ebpf/internal/unix"
 )
 
 type kconfigMetaKey struct{}
@@ -1139,7 +1138,7 @@ func (ec *elfCode) loadDataSections() error {
 		}
 
 		if strings.HasPrefix(sec.Name, ".rodata") {
-			mapSpec.Flags = unix.BPF_F_RDONLY_PROG
+			mapSpec.Flags = sys.BPF_F_RDONLY_PROG
 			mapSpec.Freeze = true
 		}
 
@@ -1175,7 +1174,7 @@ func (ec *elfCode) loadKconfigSection() error {
 		KeySize:    uint32(4),
 		ValueSize:  ds.Size,
 		MaxEntries: 1,
-		Flags:      unix.BPF_F_RDONLY_PROG,
+		Flags:      sys.BPF_F_RDONLY_PROG,
 		Freeze:     true,
 		Key:        &btf.Int{Size: 4},
 		Value:      ds,
@@ -1266,10 +1265,10 @@ func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) {
 
 		var flags uint32
 		if t.flags&_SEC_SLEEPABLE > 0 {
-			flags |= unix.BPF_F_SLEEPABLE
+			flags |= sys.BPF_F_SLEEPABLE
 		}
 		if t.flags&_SEC_XDP_FRAGS > 0 {
-			flags |= unix.BPF_F_XDP_HAS_FRAGS
+			flags |= sys.BPF_F_XDP_HAS_FRAGS
 		}
 		if t.flags&_SEC_EXP_ATTACH_OPT > 0 {
 			if programType == XDP {
diff --git a/features/map.go b/features/map.go
index 8923e73..4b16e6a 100644
--- a/features/map.go
+++ b/features/map.go
@@ -40,7 +40,7 @@ func probeStorageMap(mt sys.MapType) error {
 		KeySize:        4,
 		ValueSize:      4,
 		MaxEntries:     0,
-		MapFlags:       unix.BPF_F_NO_PREALLOC,
+		MapFlags:       sys.BPF_F_NO_PREALLOC,
 		BtfKeyTypeId:   1,
 		BtfValueTypeId: 1,
 		BtfFd:          ^uint32(0),
@@ -123,7 +123,7 @@ var haveMapTypeMatrix = internal.FeatureMatrix[ebpf.MapType]{
 				MapType:   sys.BPF_MAP_TYPE_LPM_TRIE,
 				KeySize:   8,
 				ValueSize: 8,
-				MapFlags:  unix.BPF_F_NO_PREALLOC,
+				MapFlags:  sys.BPF_F_NO_PREALLOC,
 			})
 		},
 	},
@@ -227,7 +227,7 @@ func init() {
 }
 
 // MapFlags document which flags may be feature probed.
-type MapFlags = sys.MapFlags
+type MapFlags uint32
 
 // Flags which may be feature probed.
 const (
diff --git a/features/prog.go b/features/prog.go
index dc13b86..003bf00 100644
--- a/features/prog.go
+++ b/features/prog.go
@@ -185,7 +185,7 @@ var haveProgramTypeMatrix = internal.FeatureMatrix[ebpf.ProgramType]{
 		Fn: func() error {
 			return probeProgram(&ebpf.ProgramSpec{
 				Type:  ebpf.Syscall,
-				Flags: unix.BPF_F_SLEEPABLE,
+				Flags: sys.BPF_F_SLEEPABLE,
 			})
 		},
 	},
@@ -263,7 +263,7 @@ func haveProgramHelper(pt ebpf.ProgramType, helper asm.BuiltinFunc) error {
 	case ebpf.SkLookup:
 		spec.AttachType = ebpf.AttachSkLookup
 	case ebpf.Syscall:
-		spec.Flags = unix.BPF_F_SLEEPABLE
+		spec.Flags = sys.BPF_F_SLEEPABLE
 	}
 
 	prog, err := ebpf.NewProgramWithOptions(spec, ebpf.ProgramOptions{
diff --git a/internal/cmd/gentypes/main.go b/internal/cmd/gentypes/main.go
index 3fe7369..7b693ca 100644
--- a/internal/cmd/gentypes/main.go
+++ b/internal/cmd/gentypes/main.go
@@ -75,7 +75,6 @@ func generateTypes(spec *btf.Spec) ([]byte, error) {
 	typeID := &btf.Int{Size: 4}
 	pointer := &btf.Int{Size: 8}
 	logLevel := &btf.Int{Size: 4}
-	mapFlags := &btf.Int{Size: 4}
 
 	gf := &btf.GoFormatter{
 		Names: map[btf.Type]string{
@@ -85,7 +84,6 @@ func generateTypes(spec *btf.Spec) ([]byte, error) {
 			typeID:   internal.GoTypeName(sys.TypeID(0)),
 			pointer:  internal.GoTypeName(sys.Pointer{}),
 			logLevel: internal.GoTypeName(sys.LogLevel(0)),
-			mapFlags: internal.GoTypeName(sys.MapFlags(0)),
 		},
 		Identifier: internal.Identifier,
 		EnumIdentifier: func(name, element string) string {
@@ -104,6 +102,39 @@ import (
 
 `)
 
+	// Constants (aka unnamed enums)
+	var consts []btf.EnumValue
+	iter := spec.Iterate()
+	for iter.Next() {
+		e, ok := iter.Type.(*btf.Enum)
+		if !ok {
+			continue
+		}
+
+		if e.Name != "" {
+			continue
+		}
+
+		for _, value := range e.Values {
+			if strings.HasPrefix(value.Name, "BPF_") {
+				// Greedily take all values which start with BPF_
+				consts = append(consts, value)
+			}
+		}
+	}
+
+	sort.Slice(consts, func(i, j int) bool {
+		return consts[i].Name < consts[j].Name
+	})
+
+	w.WriteString("const (\n")
+	for _, c := range consts {
+		fmt.Println("const", c.Name)
+		fmt.Fprintf(w, "\t%s = %v\n", c.Name, c.Value)
+	}
+	w.WriteString(")\n")
+
+	// Typed constants (aka named enums)
 	enums := []struct {
 		goType string
 		cType  string
@@ -178,7 +209,6 @@ import (
 			"MapInfo", "bpf_map_info",
 			[]patch{
 				replace(objName, "name"),
-				replace(mapFlags, "map_flags"),
 				replace(typeID, "btf_vmlinux_value_type_id", "btf_key_type_id", "btf_value_type_id"),
 			},
 		},
@@ -241,7 +271,6 @@ import (
 			[]patch{
 				replace(objName, "map_name"),
 				replace(enumTypes["MapType"], "map_type"),
-				replace(mapFlags, "map_flags"),
 				replace(typeID, "btf_vmlinux_value_type_id", "btf_key_type_id", "btf_value_type_id"),
 			},
 		},
diff --git a/internal/sys/mapflags_string.go b/internal/sys/mapflags_string.go
deleted file mode 100644
index d9fe217..0000000
--- a/internal/sys/mapflags_string.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Code generated by "stringer -type MapFlags"; DO NOT EDIT.
-
-package sys
-
-import "strconv"
-
-func _() {
-	// An "invalid array index" compiler error signifies that the constant values have changed.
-	// Re-run the stringer command to generate them again.
-	var x [1]struct{}
-	_ = x[BPF_F_NO_PREALLOC-1]
-	_ = x[BPF_F_NO_COMMON_LRU-2]
-	_ = x[BPF_F_NUMA_NODE-4]
-	_ = x[BPF_F_RDONLY-8]
-	_ = x[BPF_F_WRONLY-16]
-	_ = x[BPF_F_STACK_BUILD_ID-32]
-	_ = x[BPF_F_ZERO_SEED-64]
-	_ = x[BPF_F_RDONLY_PROG-128]
-	_ = x[BPF_F_WRONLY_PROG-256]
-	_ = x[BPF_F_CLONE-512]
-	_ = x[BPF_F_MMAPABLE-1024]
-	_ = x[BPF_F_PRESERVE_ELEMS-2048]
-	_ = x[BPF_F_INNER_MAP-4096]
-	_ = x[BPF_F_LINK-8192]
-	_ = x[BPF_F_PATH_FD-16384]
-}
-
-const _MapFlags_name = "BPF_F_NO_PREALLOCBPF_F_NO_COMMON_LRUBPF_F_NUMA_NODEBPF_F_RDONLYBPF_F_WRONLYBPF_F_STACK_BUILD_IDBPF_F_ZERO_SEEDBPF_F_RDONLY_PROGBPF_F_WRONLY_PROGBPF_F_CLONEBPF_F_MMAPABLEBPF_F_PRESERVE_ELEMSBPF_F_INNER_MAPBPF_F_LINKBPF_F_PATH_FD"
-
-var _MapFlags_map = map[MapFlags]string{
-	1:     _MapFlags_name[0:17],
-	2:     _MapFlags_name[17:36],
-	4:     _MapFlags_name[36:51],
-	8:     _MapFlags_name[51:63],
-	16:    _MapFlags_name[63:75],
-	32:    _MapFlags_name[75:95],
-	64:    _MapFlags_name[95:110],
-	128:   _MapFlags_name[110:127],
-	256:   _MapFlags_name[127:144],
-	512:   _MapFlags_name[144:155],
-	1024:  _MapFlags_name[155:169],
-	2048:  _MapFlags_name[169:189],
-	4096:  _MapFlags_name[189:204],
-	8192:  _MapFlags_name[204:214],
-	16384: _MapFlags_name[214:227],
-}
-
-func (i MapFlags) String() string {
-	if str, ok := _MapFlags_map[i]; ok {
-		return str
-	}
-	return "MapFlags(" + strconv.FormatInt(int64(i), 10) + ")"
-}
diff --git a/internal/sys/syscall.go b/internal/sys/syscall.go
index f6b6e93..e37f4cf 100644
--- a/internal/sys/syscall.go
+++ b/internal/sys/syscall.go
@@ -133,12 +133,12 @@ func ObjInfo(fd *FD, info Info) error {
 
 // BPFObjName is a null-terminated string made up of
 // 'A-Za-z0-9_' characters.
-type ObjName [unix.BPF_OBJ_NAME_LEN]byte
+type ObjName [BPF_OBJ_NAME_LEN]byte
 
 // NewObjName truncates the result if it is too long.
 func NewObjName(name string) ObjName {
 	var result ObjName
-	copy(result[:unix.BPF_OBJ_NAME_LEN-1], name)
+	copy(result[:BPF_OBJ_NAME_LEN-1], name)
 	return result
 }
 
@@ -160,29 +160,6 @@ type BTFID uint32
 // TypeID identifies a type in a BTF blob.
 type TypeID uint32
 
-// MapFlags control map behaviour.
-type MapFlags uint32
-
-//go:generate go run golang.org/x/tools/cmd/stringer@latest -type MapFlags
-
-const (
-	BPF_F_NO_PREALLOC MapFlags = 1 << iota
-	BPF_F_NO_COMMON_LRU
-	BPF_F_NUMA_NODE
-	BPF_F_RDONLY
-	BPF_F_WRONLY
-	BPF_F_STACK_BUILD_ID
-	BPF_F_ZERO_SEED
-	BPF_F_RDONLY_PROG
-	BPF_F_WRONLY_PROG
-	BPF_F_CLONE
-	BPF_F_MMAPABLE
-	BPF_F_PRESERVE_ELEMS
-	BPF_F_INNER_MAP
-	BPF_F_LINK
-	BPF_F_PATH_FD
-)
-
 // Flags used by bpf_mprog.
 const (
 	BPF_F_REPLACE = 1 << (iota + 2)
@@ -192,6 +169,16 @@ const (
 	BPF_F_LINK_MPROG = 1 << 13 // aka BPF_F_LINK
 )
 
+// Flags used by BPF_PROG_LOAD.
+const (
+	BPF_F_SLEEPABLE          = 1 << 4
+	BPF_F_XDP_HAS_FRAGS      = 1 << 5
+	BPF_F_XDP_DEV_BOUND_ONLY = 1 << 6
+)
+
+const BPF_TAG_SIZE = 8
+const BPF_OBJ_NAME_LEN = 16
+
 // wrappedErrno wraps syscall.Errno to prevent direct comparisons with
 // syscall.E* or unix.E* constants.
 //
diff --git a/internal/sys/types.go b/internal/sys/types.go
index 70e754d..d46164a 100644
--- a/internal/sys/types.go
+++ b/internal/sys/types.go
@@ -6,6 +6,170 @@ import (
 	"unsafe"
 )
 
+const (
+	BPF_ADJ_ROOM_ENCAP_L2_MASK                 = 255
+	BPF_ADJ_ROOM_ENCAP_L2_SHIFT                = 56
+	BPF_ANY                                    = 0
+	BPF_CSUM_LEVEL_DEC                         = 2
+	BPF_CSUM_LEVEL_INC                         = 1
+	BPF_CSUM_LEVEL_QUERY                       = 0
+	BPF_CSUM_LEVEL_RESET                       = 3
+	BPF_EXIST                                  = 2
+	BPF_FIB_LKUP_RET_BLACKHOLE                 = 1
+	BPF_FIB_LKUP_RET_FRAG_NEEDED               = 8
+	BPF_FIB_LKUP_RET_FWD_DISABLED              = 5
+	BPF_FIB_LKUP_RET_NOT_FWDED                 = 4
+	BPF_FIB_LKUP_RET_NO_NEIGH                  = 7
+	BPF_FIB_LKUP_RET_NO_SRC_ADDR               = 9
+	BPF_FIB_LKUP_RET_PROHIBIT                  = 3
+	BPF_FIB_LKUP_RET_SUCCESS                   = 0
+	BPF_FIB_LKUP_RET_UNREACHABLE               = 2
+	BPF_FIB_LKUP_RET_UNSUPP_LWT                = 6
+	BPF_FIB_LOOKUP_DIRECT                      = 1
+	BPF_FIB_LOOKUP_OUTPUT                      = 2
+	BPF_FIB_LOOKUP_SKIP_NEIGH                  = 4
+	BPF_FIB_LOOKUP_SRC                         = 16
+	BPF_FIB_LOOKUP_TBID                        = 8
+	BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG        = 1
+	BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP         = 4
+	BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL    = 2
+	BPF_F_ADJ_ROOM_DECAP_L3_IPV4               = 128
+	BPF_F_ADJ_ROOM_DECAP_L3_IPV6               = 256
+	BPF_F_ADJ_ROOM_ENCAP_L2_ETH                = 64
+	BPF_F_ADJ_ROOM_ENCAP_L3_IPV4               = 2
+	BPF_F_ADJ_ROOM_ENCAP_L3_IPV6               = 4
+	BPF_F_ADJ_ROOM_ENCAP_L4_GRE                = 8
+	BPF_F_ADJ_ROOM_ENCAP_L4_UDP                = 16
+	BPF_F_ADJ_ROOM_FIXED_GSO                   = 1
+	BPF_F_ADJ_ROOM_NO_CSUM_RESET               = 32
+	BPF_F_BPRM_SECUREEXEC                      = 1
+	BPF_F_BROADCAST                            = 8
+	BPF_F_CLONE                                = 512
+	BPF_F_CTXLEN_MASK                          = 4503595332403200
+	BPF_F_CURRENT_CPU                          = 4294967295
+	BPF_F_CURRENT_NETNS                        = 18446744073709551615
+	BPF_F_DONT_FRAGMENT                        = 4
+	BPF_F_EXCLUDE_INGRESS                      = 16
+	BPF_F_FAST_STACK_CMP                       = 512
+	BPF_F_GET_BRANCH_RECORDS_SIZE              = 1
+	BPF_F_HDR_FIELD_MASK                       = 15
+	BPF_F_INDEX_MASK                           = 4294967295
+	BPF_F_INGRESS                              = 1
+	BPF_F_INNER_MAP                            = 4096
+	BPF_F_INVALIDATE_HASH                      = 2
+	BPF_F_KPROBE_MULTI_RETURN                  = 1
+	BPF_F_LINK                                 = 8192
+	BPF_F_LOCK                                 = 4
+	BPF_F_MARK_ENFORCE                         = 64
+	BPF_F_MARK_MANGLED_0                       = 32
+	BPF_F_MMAPABLE                             = 1024
+	BPF_F_NEIGH                                = 2
+	BPF_F_NEXTHOP                              = 8
+	BPF_F_NO_COMMON_LRU                        = 2
+	BPF_F_NO_PREALLOC                          = 1
+	BPF_F_NO_TUNNEL_KEY                        = 16
+	BPF_F_NUMA_NODE                            = 4
+	BPF_F_PATH_FD                              = 16384
+	BPF_F_PEER                                 = 4
+	BPF_F_PRESERVE_ELEMS                       = 2048
+	BPF_F_PSEUDO_HDR                           = 16
+	BPF_F_RDONLY                               = 8
+	BPF_F_RDONLY_PROG                          = 128
+	BPF_F_RECOMPUTE_CSUM                       = 1
+	BPF_F_REUSE_STACKID                        = 1024
+	BPF_F_SEQ_NUMBER                           = 8
+	BPF_F_SKIP_FIELD_MASK                      = 255
+	BPF_F_STACK_BUILD_ID                       = 32
+	BPF_F_SYSCTL_BASE_NAME                     = 1
+	BPF_F_TIMER_ABS                            = 1
+	BPF_F_TIMER_CPU_PIN                        = 2
+	BPF_F_TUNINFO_FLAGS                        = 16
+	BPF_F_TUNINFO_IPV6                         = 1
+	BPF_F_UPROBE_MULTI_RETURN                  = 1
+	BPF_F_USER_BUILD_ID                        = 2048
+	BPF_F_USER_STACK                           = 256
+	BPF_F_WRONLY                               = 16
+	BPF_F_WRONLY_PROG                          = 256
+	BPF_F_ZERO_CSUM_TX                         = 2
+	BPF_F_ZERO_SEED                            = 64
+	BPF_LOAD_HDR_OPT_TCP_SYN                   = 1
+	BPF_LOCAL_STORAGE_GET_F_CREATE             = 1
+	BPF_MAX_LOOPS                              = 8388608
+	BPF_MAX_TRAMP_LINKS                        = 38
+	BPF_NOEXIST                                = 1
+	BPF_RB_AVAIL_DATA                          = 0
+	BPF_RB_CONS_POS                            = 2
+	BPF_RB_FORCE_WAKEUP                        = 2
+	BPF_RB_NO_WAKEUP                           = 1
+	BPF_RB_PROD_POS                            = 3
+	BPF_RB_RING_SIZE                           = 1
+	BPF_REG_0                                  = 0
+	BPF_REG_1                                  = 1
+	BPF_REG_10                                 = 10
+	BPF_REG_2                                  = 2
+	BPF_REG_3                                  = 3
+	BPF_REG_4                                  = 4
+	BPF_REG_5                                  = 5
+	BPF_REG_6                                  = 6
+	BPF_REG_7                                  = 7
+	BPF_REG_8                                  = 8
+	BPF_REG_9                                  = 9
+	BPF_RINGBUF_BUSY_BIT                       = 2147483648
+	BPF_RINGBUF_DISCARD_BIT                    = 1073741824
+	BPF_RINGBUF_HDR_SZ                         = 8
+	BPF_SKB_TSTAMP_DELIVERY_MONO               = 1
+	BPF_SKB_TSTAMP_UNSPEC                      = 0
+	BPF_SK_LOOKUP_F_NO_REUSEPORT               = 2
+	BPF_SK_LOOKUP_F_REPLACE                    = 1
+	BPF_SK_STORAGE_GET_F_CREATE                = 1
+	BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB         = 4
+	BPF_SOCK_OPS_ALL_CB_FLAGS                  = 127
+	BPF_SOCK_OPS_BASE_RTT                      = 7
+	BPF_SOCK_OPS_HDR_OPT_LEN_CB                = 14
+	BPF_SOCK_OPS_NEEDS_ECN                     = 6
+	BPF_SOCK_OPS_PARSE_ALL_HDR_OPT_CB_FLAG     = 16
+	BPF_SOCK_OPS_PARSE_HDR_OPT_CB              = 13
+	BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG = 32
+	BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB        = 5
+	BPF_SOCK_OPS_RETRANS_CB                    = 9
+	BPF_SOCK_OPS_RETRANS_CB_FLAG               = 2
+	BPF_SOCK_OPS_RTO_CB                        = 8
+	BPF_SOCK_OPS_RTO_CB_FLAG                   = 1
+	BPF_SOCK_OPS_RTT_CB                        = 12
+	BPF_SOCK_OPS_RTT_CB_FLAG                   = 8
+	BPF_SOCK_OPS_RWND_INIT                     = 2
+	BPF_SOCK_OPS_STATE_CB                      = 10
+	BPF_SOCK_OPS_STATE_CB_FLAG                 = 4
+	BPF_SOCK_OPS_TCP_CONNECT_CB                = 3
+	BPF_SOCK_OPS_TCP_LISTEN_CB                 = 11
+	BPF_SOCK_OPS_TIMEOUT_INIT                  = 1
+	BPF_SOCK_OPS_VOID                          = 0
+	BPF_SOCK_OPS_WRITE_HDR_OPT_CB              = 15
+	BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG         = 64
+	BPF_STRUCT_OPS_TYPE_bpf_dummy_ops          = 0
+	BPF_STRUCT_OPS_TYPE_tcp_congestion_ops     = 1
+	BPF_TASK_ITER_ALL_PROCS                    = 0
+	BPF_TASK_ITER_ALL_THREADS                  = 1
+	BPF_TASK_ITER_PROC_THREADS                 = 2
+	BPF_TCP_BOUND_INACTIVE                     = 13
+	BPF_TCP_CLOSE                              = 7
+	BPF_TCP_CLOSE_WAIT                         = 8
+	BPF_TCP_CLOSING                            = 11
+	BPF_TCP_ESTABLISHED                        = 1
+	BPF_TCP_FIN_WAIT1                          = 4
+	BPF_TCP_FIN_WAIT2                          = 5
+	BPF_TCP_LAST_ACK                           = 9
+	BPF_TCP_LISTEN                             = 10
+	BPF_TCP_MAX_STATES                         = 14
+	BPF_TCP_NEW_SYN_RECV                       = 12
+	BPF_TCP_SYN_RECV                           = 3
+	BPF_TCP_SYN_SENT                           = 2
+	BPF_TCP_TIME_WAIT                          = 6
+	BPF_WRITE_HDR_TCP_CURRENT_MSS              = 1
+	BPF_WRITE_HDR_TCP_SYNACK_COOKIE            = 2
+	BPF_XFRM_STATE_OPTS_SZ                     = 36
+)
+
 type AdjRoomMode uint32
 
 const (
@@ -537,7 +701,7 @@ type MapInfo struct {
 	KeySize               uint32
 	ValueSize             uint32
 	MaxEntries            uint32
-	MapFlags              MapFlags
+	MapFlags              uint32
 	Name                  ObjName
 	Ifindex               uint32
 	BtfVmlinuxValueTypeId TypeID
@@ -886,7 +1050,7 @@ type MapCreateAttr struct {
 	KeySize               uint32
 	ValueSize             uint32
 	MaxEntries            uint32
-	MapFlags              MapFlags
+	MapFlags              uint32
 	InnerMapFd            uint32
 	NumaNode              uint32
 	MapName               ObjName
diff --git a/link/kprobe_multi.go b/link/kprobe_multi.go
index f7a8291..3c2ce6d 100644
--- a/link/kprobe_multi.go
+++ b/link/kprobe_multi.go
@@ -60,7 +60,7 @@ func KprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions) (Link, error) {
 //
 // Requires at least Linux 5.18.
 func KretprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions) (Link, error) {
-	return kprobeMulti(prog, opts, unix.BPF_F_KPROBE_MULTI_RETURN)
+	return kprobeMulti(prog, opts, sys.BPF_F_KPROBE_MULTI_RETURN)
 }
 
 func kprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions, flags uint32) (Link, error) {
diff --git a/link/uprobe_multi.go b/link/uprobe_multi.go
index aea807b..db45ae6 100644
--- a/link/uprobe_multi.go
+++ b/link/uprobe_multi.go
@@ -47,7 +47,7 @@ func (ex *Executable) UretprobeMulti(symbols []string, prog *ebpf.Program, opts
 	// The return probe is not limited for symbols entry, so there's no special
 	// setup for return uprobes (other than the extra flag). The symbols, opts.Offsets
 	// and opts.Addresses arrays follow the same logic as for entry uprobes.
-	return ex.uprobeMulti(symbols, prog, opts, unix.BPF_F_UPROBE_MULTI_RETURN)
+	return ex.uprobeMulti(symbols, prog, opts, sys.BPF_F_UPROBE_MULTI_RETURN)
 }
 
 func (ex *Executable) uprobeMulti(symbols []string, prog *ebpf.Program, opts *UprobeMultiOptions, flags uint32) (Link, error) {
diff --git a/map.go b/map.go
index 0b62101..128767b 100644
--- a/map.go
+++ b/map.go
@@ -66,7 +66,7 @@ type MapSpec struct {
 	Pinning PinType
 
 	// Specify numa node during map creation
-	// (effective only if unix.BPF_F_NUMA_NODE flag is set,
+	// (effective only if sys.BPF_F_NUMA_NODE flag is set,
 	// which can be imported from golang.org/x/sys/unix)
 	NumaNode uint32
 
@@ -222,7 +222,7 @@ func (ms *MapSpec) Compatible(m *Map) error {
 
 	// BPF_F_RDONLY_PROG is set unconditionally for devmaps. Explicitly allow this
 	// mismatch.
-	if !((ms.Type == DevMap || ms.Type == DevMapHash) && m.flags^ms.Flags == unix.BPF_F_RDONLY_PROG) &&
+	if !((ms.Type == DevMap || ms.Type == DevMapHash) && m.flags^ms.Flags == sys.BPF_F_RDONLY_PROG) &&
 		m.flags != ms.Flags {
 		diffs = append(diffs, fmt.Sprintf("Flags: %d changed to %d", m.flags, ms.Flags))
 	}
@@ -416,7 +416,7 @@ func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions) (_ *Map, err erro
 		KeySize:    spec.KeySize,
 		ValueSize:  spec.ValueSize,
 		MaxEntries: spec.MaxEntries,
-		MapFlags:   sys.MapFlags(spec.Flags),
+		MapFlags:   spec.Flags,
 		NumaNode:   spec.NumaNode,
 	}
 
@@ -474,7 +474,7 @@ func handleMapCreateError(attr sys.MapCreateAttr, spec *MapSpec, err error) erro
 	if errors.Is(err, unix.EINVAL) && spec.Type == UnspecifiedMap {
 		return fmt.Errorf("map create: cannot use type %s", UnspecifiedMap)
 	}
-	if errors.Is(err, unix.EINVAL) && spec.Flags&unix.BPF_F_NO_PREALLOC > 0 {
+	if errors.Is(err, unix.EINVAL) && spec.Flags&sys.BPF_F_NO_PREALLOC > 0 {
 		return fmt.Errorf("map create: %w (noPrealloc flag may be incompatible with map type %s)", err, spec.Type)
 	}
 
@@ -484,22 +484,22 @@ func handleMapCreateError(attr sys.MapCreateAttr, spec *MapSpec, err error) erro
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
 	}
-	if spec.Flags&(unix.BPF_F_RDONLY_PROG|unix.BPF_F_WRONLY_PROG) > 0 || spec.Freeze {
+	if spec.Flags&(sys.BPF_F_RDONLY_PROG|sys.BPF_F_WRONLY_PROG) > 0 || spec.Freeze {
 		if haveFeatErr := haveMapMutabilityModifiers(); haveFeatErr != nil {
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
 	}
-	if spec.Flags&unix.BPF_F_MMAPABLE > 0 {
+	if spec.Flags&sys.BPF_F_MMAPABLE > 0 {
 		if haveFeatErr := haveMmapableMaps(); haveFeatErr != nil {
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
 	}
-	if spec.Flags&unix.BPF_F_INNER_MAP > 0 {
+	if spec.Flags&sys.BPF_F_INNER_MAP > 0 {
 		if haveFeatErr := haveInnerMaps(); haveFeatErr != nil {
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
 	}
-	if spec.Flags&unix.BPF_F_NO_PREALLOC > 0 {
+	if spec.Flags&sys.BPF_F_NO_PREALLOC > 0 {
 		if haveFeatErr := haveNoPreallocMaps(); haveFeatErr != nil {
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
@@ -604,7 +604,7 @@ func (m *Map) Handle() (*btf.Handle, error) {
 type MapLookupFlags uint64
 
 // LookupLock look up the value of a spin-locked map.
-const LookupLock MapLookupFlags = unix.BPF_F_LOCK
+const LookupLock MapLookupFlags = sys.BPF_F_LOCK
 
 // Lookup retrieves a value from a Map.
 //
diff --git a/ringbuf/reader.go b/ringbuf/reader.go
index 3d3ba0e..f76de32 100644
--- a/ringbuf/reader.go
+++ b/ringbuf/reader.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/cilium/ebpf"
 	"github.com/cilium/ebpf/internal/epoll"
+	"github.com/cilium/ebpf/internal/sys"
 	"github.com/cilium/ebpf/internal/unix"
 )
 
@@ -26,15 +27,15 @@ type ringbufHeader struct {
 }
 
 func (rh *ringbufHeader) isBusy() bool {
-	return rh.Len&unix.BPF_RINGBUF_BUSY_BIT != 0
+	return rh.Len&sys.BPF_RINGBUF_BUSY_BIT != 0
 }
 
 func (rh *ringbufHeader) isDiscard() bool {
-	return rh.Len&unix.BPF_RINGBUF_DISCARD_BIT != 0
+	return rh.Len&sys.BPF_RINGBUF_DISCARD_BIT != 0
 }
 
 func (rh *ringbufHeader) dataLen() int {
-	return int(rh.Len & ^uint32(unix.BPF_RINGBUF_BUSY_BIT|unix.BPF_RINGBUF_DISCARD_BIT))
+	return int(rh.Len & ^uint32(sys.BPF_RINGBUF_BUSY_BIT|sys.BPF_RINGBUF_DISCARD_BIT))
 }
 
 type Record struct {
diff --git a/ringbuf/ring.go b/ringbuf/ring.go
index 8f8f4bc..b864966 100644
--- a/ringbuf/ring.go
+++ b/ringbuf/ring.go
@@ -9,6 +9,7 @@ import (
 	"unsafe"
 
 	"github.com/cilium/ebpf/internal"
+	"github.com/cilium/ebpf/internal/sys"
 	"github.com/cilium/ebpf/internal/unix"
 )
 
@@ -85,7 +86,7 @@ func (rr *ringReader) readRecord(rec *Record) error {
 	for {
 		if remaining := prod - cons; remaining == 0 {
 			return errEOR
-		} else if remaining < unix.BPF_RINGBUF_HDR_SZ {
+		} else if remaining < sys.BPF_RINGBUF_HDR_SZ {
 			return fmt.Errorf("read record header: %w", io.ErrUnexpectedEOF)
 		}
 
@@ -104,7 +105,7 @@ func (rr *ringReader) readRecord(rec *Record) error {
 			return errBusy
 		}
 
-		cons += unix.BPF_RINGBUF_HDR_SZ
+		cons += sys.BPF_RINGBUF_HDR_SZ
 
 		// Data is always padded to 8 byte alignment.
 		dataLenAligned := uint64(internal.Align(header.dataLen(), 8))
diff --git a/syscalls.go b/syscalls.go
index 4aef7fa..0766e7d 100644
--- a/syscalls.go
+++ b/syscalls.go
@@ -86,7 +86,7 @@ var haveMapMutabilityModifiers = internal.NewFeatureTest("read- and write-only m
 		KeySize:    4,
 		ValueSize:  4,
 		MaxEntries: 1,
-		MapFlags:   unix.BPF_F_RDONLY_PROG,
+		MapFlags:   sys.BPF_F_RDONLY_PROG,
 	})
 	if err != nil {
 		return internal.ErrNotSupported
@@ -102,7 +102,7 @@ var haveMmapableMaps = internal.NewFeatureTest("mmapable maps", "5.5", func() er
 		KeySize:    4,
 		ValueSize:  4,
 		MaxEntries: 1,
-		MapFlags:   unix.BPF_F_MMAPABLE,
+		MapFlags:   sys.BPF_F_MMAPABLE,
 	})
 	if err != nil {
 		return internal.ErrNotSupported
@@ -118,7 +118,7 @@ var haveInnerMaps = internal.NewFeatureTest("inner maps", "5.10", func() error {
 		KeySize:    4,
 		ValueSize:  4,
 		MaxEntries: 1,
-		MapFlags:   unix.BPF_F_INNER_MAP,
+		MapFlags:   sys.BPF_F_INNER_MAP,
 	})
 
 	if err != nil {
@@ -135,7 +135,7 @@ var haveNoPreallocMaps = internal.NewFeatureTest("prealloc maps", "4.6", func()
 		KeySize:    4,
 		ValueSize:  4,
 		MaxEntries: 1,
-		MapFlags:   unix.BPF_F_NO_PREALLOC,
+		MapFlags:   sys.BPF_F_NO_PREALLOC,
 	})
 
 	if err != nil {
diff --git a/types.go b/types.go
index 542c239..b272b35 100644
--- a/types.go
+++ b/types.go
@@ -2,7 +2,6 @@ package ebpf
 
 import (
 	"github.com/cilium/ebpf/internal/sys"
-	"github.com/cilium/ebpf/internal/unix"
 )
 
 //go:generate go run golang.org/x/tools/cmd/stringer@latest -output types_string.go -type=MapType,ProgramType,PinType
@@ -263,10 +262,10 @@ func (lpo *LoadPinOptions) Marshal() uint32 {
 
 	flags := lpo.Flags
 	if lpo.ReadOnly {
-		flags |= unix.BPF_F_RDONLY
+		flags |= sys.BPF_F_RDONLY
 	}
 	if lpo.WriteOnly {
-		flags |= unix.BPF_F_WRONLY
+		flags |= sys.BPF_F_WRONLY
 	}
 	return flags
 }


Test patch:
diff --git a/elf_reader_test.go b/elf_reader_test.go
index 91b1da6..da164b4 100644
--- a/elf_reader_test.go
+++ b/elf_reader_test.go
@@ -14,8 +14,8 @@ import (
 
 	"github.com/cilium/ebpf/btf"
 	"github.com/cilium/ebpf/internal"
+	"github.com/cilium/ebpf/internal/sys"
 	"github.com/cilium/ebpf/internal/testutils"
-	"github.com/cilium/ebpf/internal/unix"
 
 	"github.com/google/go-cmp/cmp"
 	"github.com/google/go-cmp/cmp/cmpopts"
@@ -32,7 +32,7 @@ func TestLoadCollectionSpec(t *testing.T) {
 				KeySize:    4,
 				ValueSize:  8,
 				MaxEntries: 1,
-				Flags:      unix.BPF_F_NO_PREALLOC,
+				Flags:      sys.BPF_F_NO_PREALLOC,
 			},
 			"hash_map2": {
 				Name:       "hash_map2",
@@ -486,7 +486,7 @@ func TestStringSection(t *testing.T) {
 		t.Fatal("Read only data maps should be frozen")
 	}
 
-	if strMap.Flags != unix.BPF_F_RDONLY_PROG {
+	if strMap.Flags != sys.BPF_F_RDONLY_PROG {
 		t.Fatal("Read only data maps should have the prog-read-only flag set")
 	}
 
@@ -1187,22 +1187,22 @@ func TestELFSectionProgramTypes(t *testing.T) {
 		{"fentry/", Tracing, AttachTraceFEntry, 0, ""},
 		{"fmod_ret/", Tracing, AttachModifyReturn, 0, ""},
 		{"fexit/", Tracing, AttachTraceFExit, 0, ""},
-		{"fentry.s/", Tracing, AttachTraceFEntry, unix.BPF_F_SLEEPABLE, ""},
-		{"fmod_ret.s/", Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE, ""},
-		{"fexit.s/", Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE, ""},
+		{"fentry.s/", Tracing, AttachTraceFEntry, sys.BPF_F_SLEEPABLE, ""},
+		{"fmod_ret.s/", Tracing, AttachModifyReturn, sys.BPF_F_SLEEPABLE, ""},
+		{"fexit.s/", Tracing, AttachTraceFExit, sys.BPF_F_SLEEPABLE, ""},
 		{"freplace/", Extension, AttachNone, 0, ""},
 		{"lsm/foo", LSM, AttachLSMMac, 0, "foo"},
-		{"lsm.s/foo", LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE, "foo"},
+		{"lsm.s/foo", LSM, AttachLSMMac, sys.BPF_F_SLEEPABLE, "foo"},
 		{"iter/bpf_map", Tracing, AttachTraceIter, 0, "bpf_map"},
-		{"iter.s/", Tracing, AttachTraceIter, unix.BPF_F_SLEEPABLE, ""},
+		{"iter.s/", Tracing, AttachTraceIter, sys.BPF_F_SLEEPABLE, ""},
 		// Was missing sleepable.
-		{"syscall", Syscall, AttachNone, unix.BPF_F_SLEEPABLE, ""},
-		{"xdp.frags_devmap/foo", XDP, AttachXDPDevMap, unix.BPF_F_XDP_HAS_FRAGS, "foo"},
+		{"syscall", Syscall, AttachNone, sys.BPF_F_SLEEPABLE, ""},
+		{"xdp.frags_devmap/foo", XDP, AttachXDPDevMap, sys.BPF_F_XDP_HAS_FRAGS, "foo"},
 		{"xdp_devmap/foo", XDP, AttachXDPDevMap, 0, "foo"},
-		{"xdp.frags_cpumap/", XDP, AttachXDPCPUMap, unix.BPF_F_XDP_HAS_FRAGS, ""},
+		{"xdp.frags_cpumap/", XDP, AttachXDPCPUMap, sys.BPF_F_XDP_HAS_FRAGS, ""},
 		{"xdp_cpumap/", XDP, AttachXDPCPUMap, 0, ""},
 		// Used incorrect attach type.
-		{"xdp.frags/foo", XDP, AttachXDP, unix.BPF_F_XDP_HAS_FRAGS, ""},
+		{"xdp.frags/foo", XDP, AttachXDP, sys.BPF_F_XDP_HAS_FRAGS, ""},
 		{"xdp/foo", XDP, AttachNone, 0, ""},
 		{"perf_event", PerfEvent, AttachNone, 0, ""},
 		{"lwt_in", LWTIn, AttachNone, 0, ""},
diff --git a/info_test.go b/info_test.go
index 90725f5..e7db7c4 100644
--- a/info_test.go
+++ b/info_test.go
@@ -15,7 +15,6 @@ import (
 	"github.com/cilium/ebpf/internal"
 	"github.com/cilium/ebpf/internal/sys"
 	"github.com/cilium/ebpf/internal/testutils"
-	"github.com/cilium/ebpf/internal/unix"
 )
 
 func TestMapInfoFromProc(t *testing.T) {
@@ -25,7 +24,7 @@ func TestMapInfoFromProc(t *testing.T) {
 		KeySize:    4,
 		ValueSize:  5,
 		MaxEntries: 2,
-		Flags:      unix.BPF_F_NO_PREALLOC,
+		Flags:      sys.BPF_F_NO_PREALLOC,
 	})
 	testutils.SkipIfNotSupported(t, err)
 	if err != nil {
@@ -55,8 +54,8 @@ func TestMapInfoFromProc(t *testing.T) {
 		t.Error("Expected MaxEntries of 2, got", info.MaxEntries)
 	}
 
-	if info.Flags != unix.BPF_F_NO_PREALLOC {
-		t.Errorf("Expected Flags to be %d, got %d", unix.BPF_F_NO_PREALLOC, info.Flags)
+	if info.Flags != sys.BPF_F_NO_PREALLOC {
+		t.Errorf("Expected Flags to be %d, got %d", sys.BPF_F_NO_PREALLOC, info.Flags)
 	}
 
 	if info.Name != "" && info.Name != "testing" {
@@ -302,7 +301,7 @@ func BenchmarkStats(b *testing.B) {
 func testStats(prog *Program) error {
 	in := internal.EmptyBPFContext
 
-	stats, err := EnableStats(uint32(unix.BPF_STATS_RUN_TIME))
+	stats, err := EnableStats(uint32(sys.BPF_STATS_RUN_TIME))
 	if err != nil {
 		return fmt.Errorf("failed to enable stats: %v", err)
 	}
diff --git a/internal/sys/syscall_test.go b/internal/sys/syscall_test.go
index ac799c9..f4d3d63 100644
--- a/internal/sys/syscall_test.go
+++ b/internal/sys/syscall_test.go
@@ -15,8 +15,8 @@ func TestObjName(t *testing.T) {
 	if name[len(name)-1] != 0 {
 		t.Error("NewBPFObjName doesn't null terminate")
 	}
-	if len(name) != unix.BPF_OBJ_NAME_LEN {
-		t.Errorf("Name is %d instead of %d bytes long", len(name), unix.BPF_OBJ_NAME_LEN)
+	if len(name) != BPF_OBJ_NAME_LEN {
+		t.Errorf("Name is %d instead of %d bytes long", len(name), BPF_OBJ_NAME_LEN)
 	}
 }
 
diff --git a/ringbuf/reader_test.go b/ringbuf/reader_test.go
index a35f1be..47e3047 100644
--- a/ringbuf/reader_test.go
+++ b/ringbuf/reader_test.go
@@ -13,9 +13,9 @@ import (
 	"github.com/cilium/ebpf"
 	"github.com/cilium/ebpf/asm"
 	"github.com/cilium/ebpf/internal"
+	"github.com/cilium/ebpf/internal/sys"
 	"github.com/cilium/ebpf/internal/testutils"
 	"github.com/cilium/ebpf/internal/testutils/fdtrace"
-	"github.com/cilium/ebpf/internal/unix"
 )
 
 type sampleMessage struct {
@@ -259,9 +259,9 @@ func TestReaderNoWakeup(t *testing.T) {
 	testutils.SkipOnOldKernel(t, "5.8", "BPF ring buffer")
 
 	prog, events := mustOutputSamplesProg(t,
-		sampleMessage{size: 5, flags: unix.BPF_RB_NO_WAKEUP}, // Read after timeout
-		sampleMessage{size: 6, flags: unix.BPF_RB_NO_WAKEUP}, // Discard
-		sampleMessage{size: 7, flags: unix.BPF_RB_NO_WAKEUP}) // Read won't block
+		sampleMessage{size: 5, flags: sys.BPF_RB_NO_WAKEUP}, // Read after timeout
+		sampleMessage{size: 6, flags: sys.BPF_RB_NO_WAKEUP}, // Discard
+		sampleMessage{size: 7, flags: sys.BPF_RB_NO_WAKEUP}) // Read won't block
 
 	rd, err := NewReader(events)
 	if err != nil {
@@ -308,9 +308,9 @@ func TestReaderFlushPendingEvents(t *testing.T) {
 	testutils.SkipOnOldKernel(t, "5.8", "BPF ring buffer")
 
 	prog, events := mustOutputSamplesProg(t,
-		sampleMessage{size: 5, flags: unix.BPF_RB_NO_WAKEUP}, // Read after Flush
-		sampleMessage{size: 6, flags: unix.BPF_RB_NO_WAKEUP}, // Discard
-		sampleMessage{size: 7, flags: unix.BPF_RB_NO_WAKEUP}) // Read won't block
+		sampleMessage{size: 5, flags: sys.BPF_RB_NO_WAKEUP}, // Read after Flush
+		sampleMessage{size: 6, flags: sys.BPF_RB_NO_WAKEUP}, // Discard
+		sampleMessage{size: 7, flags: sys.BPF_RB_NO_WAKEUP}) // Read won't block
 
 	rd, err := NewReader(events)
 	if err != nil {