snapshot: sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1
Содержимое пина, зафиксированного в go.mod sing-box-lx, одним коммитом без истории. Полная история SagerNet/gvisor — 1.45 ГБ и клонируется в каждой CI-джобе; наша дельта — одна вставка в одну функцию, история для неё не нужна. Module path github.com/sagernet/gvisor сохранён намеренно: на него опирается replace-директива суперпроекта. Патч поверх — отдельным коммитом, чтобы дельта читалась одним git show и переносилась на новый пин копированием. SPECS/TASKS/048-GVISOR_HANDSHAKE_NIL_CRASH
This commit is contained in:
commit
2c4ae3b0a4
712 changed files with 185689 additions and 0 deletions
96
pkg/abi/linux/aio.go
Normal file
96
pkg/abi/linux/aio.go
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// AIORing is struct aio_ring, from fs/aio.c, without the trailing
|
||||
// variable-length array.
|
||||
type AIORing struct {
|
||||
ID uint32
|
||||
Nr uint32
|
||||
Head uint32
|
||||
Tail uint32
|
||||
Magic uint32
|
||||
CompatFeatures uint32
|
||||
IncompatFeatures uint32
|
||||
HeaderLength uint32
|
||||
}
|
||||
|
||||
// AIORingSize is sizeof(struct aio_ring).
|
||||
const AIORingSize = 32
|
||||
|
||||
// AIO_RING_MAGIC is fs/aio.c:AIO_RING_MAGIC, the expected value of
|
||||
// AIORing.Magic.
|
||||
const AIO_RING_MAGIC = 0xa10a10a1
|
||||
|
||||
// I/O commands.
|
||||
const (
|
||||
IOCB_CMD_PREAD = 0
|
||||
IOCB_CMD_PWRITE = 1
|
||||
IOCB_CMD_FSYNC = 2
|
||||
IOCB_CMD_FDSYNC = 3
|
||||
// 4 was the experimental IOCB_CMD_PREADX.
|
||||
IOCB_CMD_POLL = 5
|
||||
IOCB_CMD_NOOP = 6
|
||||
IOCB_CMD_PREADV = 7
|
||||
IOCB_CMD_PWRITEV = 8
|
||||
)
|
||||
|
||||
// I/O flags.
|
||||
const (
|
||||
IOCB_FLAG_RESFD = 1
|
||||
IOCB_FLAG_IOPRIO = 2
|
||||
)
|
||||
|
||||
// IOCallback describes an I/O request.
|
||||
//
|
||||
// The priority field is currently ignored in the implementation below. Also
|
||||
// note that the IOCB_FLAG_RESFD feature is not supported.
|
||||
//
|
||||
// +marshal
|
||||
type IOCallback struct {
|
||||
Data uint64
|
||||
Key uint32
|
||||
_ uint32
|
||||
|
||||
OpCode uint16
|
||||
ReqPrio int16
|
||||
FD int32
|
||||
|
||||
Buf uint64
|
||||
Bytes uint64
|
||||
Offset int64
|
||||
|
||||
Reserved2 uint64
|
||||
Flags uint32
|
||||
|
||||
// eventfd to signal if IOCB_FLAG_RESFD is set in flags.
|
||||
ResFD int32
|
||||
}
|
||||
|
||||
// IOEvent describes an I/O result.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type IOEvent struct {
|
||||
Data uint64
|
||||
Obj uint64
|
||||
Result int64
|
||||
Result2 int64
|
||||
}
|
||||
|
||||
// IOEventSize is the size of an ioEvent encoded.
|
||||
var IOEventSize = binary.Size(IOEvent{})
|
||||
24
pkg/abi/linux/arch_amd64.go
Normal file
24
pkg/abi/linux/arch_amd64.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build amd64
|
||||
// +build amd64
|
||||
|
||||
package linux
|
||||
|
||||
// Start and end addresses of the vsyscall page.
|
||||
const (
|
||||
VSyscallStartAddr uint64 = 0xffffffffff600000
|
||||
VSyscallEndAddr uint64 = 0xffffffffff601000
|
||||
)
|
||||
23
pkg/abi/linux/audit.go
Normal file
23
pkg/abi/linux/audit.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Audit numbers identify different system call APIs, from <uapi/linux/audit.h>
|
||||
const (
|
||||
// AUDIT_ARCH_X86_64 identifies AMD64.
|
||||
AUDIT_ARCH_X86_64 = 0xc000003e
|
||||
// AUDIT_ARCH_AARCH64 identifies ARM64.
|
||||
AUDIT_ARCH_AARCH64 = 0xc00000b7
|
||||
)
|
||||
35
pkg/abi/linux/bpf.go
Normal file
35
pkg/abi/linux/bpf.go
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// BPFInstruction is a raw BPF virtual machine instruction.
|
||||
//
|
||||
// +marshal slice:BPFInstructionSlice
|
||||
// +stateify savable
|
||||
type BPFInstruction struct {
|
||||
// OpCode is the operation to execute.
|
||||
OpCode uint16
|
||||
|
||||
// JumpIfTrue is the number of instructions to skip if OpCode is a
|
||||
// conditional instruction and the condition is true.
|
||||
JumpIfTrue uint8
|
||||
|
||||
// JumpIfFalse is the number of instructions to skip if OpCode is a
|
||||
// conditional instruction and the condition is false.
|
||||
JumpIfFalse uint8
|
||||
|
||||
// K is a constant parameter. The meaning depends on the value of OpCode.
|
||||
K uint32
|
||||
}
|
||||
337
pkg/abi/linux/capability.go
Normal file
337
pkg/abi/linux/capability.go
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A Capability represents the ability to perform a privileged operation.
|
||||
type Capability int
|
||||
|
||||
// Capabilities defined by Linux. Taken from the kernel's
|
||||
// include/uapi/linux/capability.h. See capabilities(7) or that file for more
|
||||
// detailed capability descriptions.
|
||||
const (
|
||||
CAP_CHOWN = Capability(0)
|
||||
CAP_DAC_OVERRIDE = Capability(1)
|
||||
CAP_DAC_READ_SEARCH = Capability(2)
|
||||
CAP_FOWNER = Capability(3)
|
||||
CAP_FSETID = Capability(4)
|
||||
CAP_KILL = Capability(5)
|
||||
CAP_SETGID = Capability(6)
|
||||
CAP_SETUID = Capability(7)
|
||||
CAP_SETPCAP = Capability(8)
|
||||
CAP_LINUX_IMMUTABLE = Capability(9)
|
||||
CAP_NET_BIND_SERVICE = Capability(10)
|
||||
CAP_NET_BROADCAST = Capability(11)
|
||||
CAP_NET_ADMIN = Capability(12)
|
||||
CAP_NET_RAW = Capability(13)
|
||||
CAP_IPC_LOCK = Capability(14)
|
||||
CAP_IPC_OWNER = Capability(15)
|
||||
CAP_SYS_MODULE = Capability(16)
|
||||
CAP_SYS_RAWIO = Capability(17)
|
||||
CAP_SYS_CHROOT = Capability(18)
|
||||
CAP_SYS_PTRACE = Capability(19)
|
||||
CAP_SYS_PACCT = Capability(20)
|
||||
CAP_SYS_ADMIN = Capability(21)
|
||||
CAP_SYS_BOOT = Capability(22)
|
||||
CAP_SYS_NICE = Capability(23)
|
||||
CAP_SYS_RESOURCE = Capability(24)
|
||||
CAP_SYS_TIME = Capability(25)
|
||||
CAP_SYS_TTY_CONFIG = Capability(26)
|
||||
CAP_MKNOD = Capability(27)
|
||||
CAP_LEASE = Capability(28)
|
||||
CAP_AUDIT_WRITE = Capability(29)
|
||||
CAP_AUDIT_CONTROL = Capability(30)
|
||||
CAP_SETFCAP = Capability(31)
|
||||
CAP_MAC_OVERRIDE = Capability(32)
|
||||
CAP_MAC_ADMIN = Capability(33)
|
||||
CAP_SYSLOG = Capability(34)
|
||||
CAP_WAKE_ALARM = Capability(35)
|
||||
CAP_BLOCK_SUSPEND = Capability(36)
|
||||
CAP_AUDIT_READ = Capability(37)
|
||||
CAP_PERFMON = Capability(38)
|
||||
CAP_BPF = Capability(39)
|
||||
CAP_CHECKPOINT_RESTORE = Capability(40)
|
||||
|
||||
// CAP_LAST_CAP is the highest-numbered capability.
|
||||
// Search for "CAP_LAST_CAP" to find other places that need to change.
|
||||
CAP_LAST_CAP = CAP_CHECKPOINT_RESTORE
|
||||
)
|
||||
|
||||
// Ok returns true if cp is a supported capability.
|
||||
func (cp Capability) Ok() bool {
|
||||
return cp >= 0 && cp <= CAP_LAST_CAP
|
||||
}
|
||||
|
||||
// String returns the capability name.
|
||||
func (cp Capability) String() string {
|
||||
switch cp {
|
||||
case CAP_CHOWN:
|
||||
return "CAP_CHOWN"
|
||||
case CAP_DAC_OVERRIDE:
|
||||
return "CAP_DAC_OVERRIDE"
|
||||
case CAP_DAC_READ_SEARCH:
|
||||
return "CAP_DAC_READ_SEARCH"
|
||||
case CAP_FOWNER:
|
||||
return "CAP_FOWNER"
|
||||
case CAP_FSETID:
|
||||
return "CAP_FSETID"
|
||||
case CAP_KILL:
|
||||
return "CAP_KILL"
|
||||
case CAP_SETGID:
|
||||
return "CAP_SETGID"
|
||||
case CAP_SETUID:
|
||||
return "CAP_SETUID"
|
||||
case CAP_SETPCAP:
|
||||
return "CAP_SETPCAP"
|
||||
case CAP_LINUX_IMMUTABLE:
|
||||
return "CAP_LINUX_IMMUTABLE"
|
||||
case CAP_NET_BIND_SERVICE:
|
||||
return "CAP_NET_BIND_SERVICE"
|
||||
case CAP_NET_BROADCAST:
|
||||
return "CAP_NET_BROADCAST"
|
||||
case CAP_NET_ADMIN:
|
||||
return "CAP_NET_ADMIN"
|
||||
case CAP_NET_RAW:
|
||||
return "CAP_NET_RAW"
|
||||
case CAP_IPC_LOCK:
|
||||
return "CAP_IPC_LOCK"
|
||||
case CAP_IPC_OWNER:
|
||||
return "CAP_IPC_OWNER"
|
||||
case CAP_SYS_MODULE:
|
||||
return "CAP_SYS_MODULE"
|
||||
case CAP_SYS_RAWIO:
|
||||
return "CAP_SYS_RAWIO"
|
||||
case CAP_SYS_CHROOT:
|
||||
return "CAP_SYS_CHROOT"
|
||||
case CAP_SYS_PTRACE:
|
||||
return "CAP_SYS_PTRACE"
|
||||
case CAP_SYS_PACCT:
|
||||
return "CAP_SYS_PACCT"
|
||||
case CAP_SYS_ADMIN:
|
||||
return "CAP_SYS_ADMIN"
|
||||
case CAP_SYS_BOOT:
|
||||
return "CAP_SYS_BOOT"
|
||||
case CAP_SYS_NICE:
|
||||
return "CAP_SYS_NICE"
|
||||
case CAP_SYS_RESOURCE:
|
||||
return "CAP_SYS_RESOURCE"
|
||||
case CAP_SYS_TIME:
|
||||
return "CAP_SYS_TIME"
|
||||
case CAP_SYS_TTY_CONFIG:
|
||||
return "CAP_SYS_TTY_CONFIG"
|
||||
case CAP_MKNOD:
|
||||
return "CAP_MKNOD"
|
||||
case CAP_LEASE:
|
||||
return "CAP_LEASE"
|
||||
case CAP_AUDIT_WRITE:
|
||||
return "CAP_AUDIT_WRITE"
|
||||
case CAP_AUDIT_CONTROL:
|
||||
return "CAP_AUDIT_CONTROL"
|
||||
case CAP_SETFCAP:
|
||||
return "CAP_SETFCAP"
|
||||
case CAP_MAC_OVERRIDE:
|
||||
return "CAP_MAC_OVERRIDE"
|
||||
case CAP_MAC_ADMIN:
|
||||
return "CAP_MAC_ADMIN"
|
||||
case CAP_SYSLOG:
|
||||
return "CAP_SYSLOG"
|
||||
case CAP_WAKE_ALARM:
|
||||
return "CAP_WAKE_ALARM"
|
||||
case CAP_BLOCK_SUSPEND:
|
||||
return "CAP_BLOCK_SUSPEND"
|
||||
case CAP_AUDIT_READ:
|
||||
return "CAP_AUDIT_READ"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
// TrimmedString returns the capability name without the "CAP_" prefix.
|
||||
func (cp Capability) TrimmedString() string {
|
||||
const capPrefix = "CAP_"
|
||||
s := cp.String()
|
||||
if !strings.HasPrefix(s, capPrefix) {
|
||||
return s
|
||||
}
|
||||
// This could use strings.TrimPrefix, but that function doesn't guarantee
|
||||
// that it won't allocate a new string, whereas string slicing does.
|
||||
// In the case of this function, since Capability.String returns a constant
|
||||
// string, the underlying set of bytes backing that string will never be
|
||||
// garbage-collected. Therefore, we always want to use a string slice that
|
||||
// points to this same constant set of bytes, rather than risking
|
||||
// allocating a new string.
|
||||
return s[len(capPrefix):]
|
||||
}
|
||||
|
||||
// CapabilityFromString converts a string to a capability.
|
||||
// If the capability doesn't exist, its second return value is `false`.
|
||||
// The capability name is expected to include the "CAP_" prefix.
|
||||
func CapabilityFromString(capability string) (Capability, bool) {
|
||||
for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
|
||||
if !cp.Ok() {
|
||||
continue
|
||||
}
|
||||
if cp.String() == capability {
|
||||
return cp, true
|
||||
}
|
||||
}
|
||||
return -1, false
|
||||
}
|
||||
|
||||
// AllCapabilities returns a list of all defined capabilities.
|
||||
func AllCapabilities() []Capability {
|
||||
allCapapabilities := make([]Capability, 0, CAP_LAST_CAP+1)
|
||||
for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
|
||||
if !cp.Ok() {
|
||||
continue
|
||||
}
|
||||
allCapapabilities = append(allCapapabilities, cp)
|
||||
}
|
||||
return allCapapabilities
|
||||
}
|
||||
|
||||
// Version numbers used by the capget/capset syscalls, defined in Linux's
|
||||
// include/uapi/linux/capability.h.
|
||||
const (
|
||||
// LINUX_CAPABILITY_VERSION_1 causes the data pointer to be
|
||||
// interpreted as a pointer to a single cap_user_data_t. Since capability
|
||||
// sets are 64 bits and the "capability sets" in cap_user_data_t are 32
|
||||
// bits only, this causes the upper 32 bits to be implicitly 0.
|
||||
LINUX_CAPABILITY_VERSION_1 = 0x19980330
|
||||
|
||||
// LINUX_CAPABILITY_VERSION_2 and LINUX_CAPABILITY_VERSION_3 cause the
|
||||
// data pointer to be interpreted as a pointer to an array of 2
|
||||
// cap_user_data_t, using the second to store the 32 MSB of each capability
|
||||
// set. Versions 2 and 3 are identical, but Linux printk's a warning on use
|
||||
// of version 2 due to a userspace API defect.
|
||||
LINUX_CAPABILITY_VERSION_2 = 0x20071026
|
||||
LINUX_CAPABILITY_VERSION_3 = 0x20080522
|
||||
|
||||
// HighestCapabilityVersion is the highest supported
|
||||
// LINUX_CAPABILITY_VERSION_* version.
|
||||
HighestCapabilityVersion = LINUX_CAPABILITY_VERSION_3
|
||||
)
|
||||
|
||||
// Constants that are used by file capability extended attributes, defined
|
||||
// in Linux's include/uapi/linux/capability.h.
|
||||
const (
|
||||
// VFS_CAP_FLAGS_EFFECTIVE allows the effective capability set to be
|
||||
// initialized with the permitted file capabilities.
|
||||
VFS_CAP_FLAGS_EFFECTIVE = 0x000001
|
||||
// VFS_CAP_REVISION_2 allows for file capability masks that are 64
|
||||
// bits in size, and was necessary as the number of supported
|
||||
// capabilities grew beyond 32.
|
||||
VFS_CAP_REVISION_2 = 0x02000000
|
||||
// VFS_CAP_REVISION_3 are provided to support namespaced file capabilities.
|
||||
// As with version 2 file capabilities, version 3 capability
|
||||
// masks are 64 bits in size. But in addition, the root user
|
||||
// ID of namespace is encoded in the security.capability
|
||||
// extended attribute.
|
||||
VFS_CAP_REVISION_3 = 0x03000000
|
||||
VFS_CAP_REVISION_MASK = 0xFF000000
|
||||
// XATTR_CAPS_SZ_2 is sizeof(struct vfs_cap_data).
|
||||
XATTR_CAPS_SZ_2 = 20
|
||||
// XATTR_CAPS_SZ_3 is sizeof(struct vfs_ns_cap_data).
|
||||
XATTR_CAPS_SZ_3 = 24
|
||||
)
|
||||
|
||||
// VfsCapData is equivalent to Linux's struct vfs_cap_data.
|
||||
//
|
||||
// +marshal
|
||||
type VfsCapData struct {
|
||||
MagicEtc uint32
|
||||
PermittedLo uint32
|
||||
InheritableLo uint32
|
||||
PermittedHi uint32
|
||||
InheritableHi uint32
|
||||
}
|
||||
|
||||
// Permitted returns the permitted capability set.
|
||||
func (c *VfsCapData) Permitted() uint64 {
|
||||
return uint64(c.PermittedHi)<<32 | uint64(c.PermittedLo)
|
||||
}
|
||||
|
||||
// Inheritable returns the inheritable capability set.
|
||||
func (c *VfsCapData) Inheritable() uint64 {
|
||||
return uint64(c.InheritableHi)<<32 | uint64(c.InheritableLo)
|
||||
}
|
||||
|
||||
// IsRevision2 returns true if c is v2.
|
||||
func (c *VfsCapData) IsRevision2() bool {
|
||||
return (c.MagicEtc & VFS_CAP_REVISION_MASK) == VFS_CAP_REVISION_2
|
||||
}
|
||||
|
||||
// ToString marshals c into bytes and returns it as a string.
|
||||
func (c *VfsCapData) ToString() string {
|
||||
buf := make([]byte, c.SizeBytes())
|
||||
c.MarshalUnsafe(buf)
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
// VfsNsCapData is equivalent to Linux's struct vfs_ns_cap_data.
|
||||
//
|
||||
// +marshal
|
||||
type VfsNsCapData struct {
|
||||
VfsCapData
|
||||
RootID uint32
|
||||
}
|
||||
|
||||
// ConvertToV3 converts c to v3 file capabilities.
|
||||
func (c *VfsNsCapData) ConvertToV3(rootid uint32) {
|
||||
c.RootID = rootid
|
||||
if c.IsRevision2() {
|
||||
// Change to v3 while retaining the effective bit.
|
||||
c.MagicEtc = VFS_CAP_REVISION_3 | c.MagicEtc&VFS_CAP_FLAGS_EFFECTIVE
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertToV2 converts c to v2 file capabilities.
|
||||
func (c *VfsNsCapData) ConvertToV2() {
|
||||
c.RootID = 0
|
||||
if !c.IsRevision2() {
|
||||
// Change to v2 while retaining the effective bit.
|
||||
c.MagicEtc = VFS_CAP_REVISION_2 | c.MagicEtc&VFS_CAP_FLAGS_EFFECTIVE
|
||||
}
|
||||
}
|
||||
|
||||
// ToString marshals c into bytes and returns it as a string.
|
||||
func (c *VfsNsCapData) ToString() string {
|
||||
if c.IsRevision2() {
|
||||
return c.VfsCapData.ToString()
|
||||
}
|
||||
buf := make([]byte, c.SizeBytes())
|
||||
c.MarshalUnsafe(buf)
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
// CapUserHeader is equivalent to Linux's cap_user_header_t.
|
||||
//
|
||||
// +marshal
|
||||
type CapUserHeader struct {
|
||||
Version uint32
|
||||
Pid int32
|
||||
}
|
||||
|
||||
// CapUserData is equivalent to Linux's cap_user_data_t.
|
||||
//
|
||||
// +marshal slice:CapUserDataSlice
|
||||
type CapUserData struct {
|
||||
Effective uint32
|
||||
Permitted uint32
|
||||
Inheritable uint32
|
||||
}
|
||||
71
pkg/abi/linux/clone.go
Normal file
71
pkg/abi/linux/clone.go
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Clone constants per clone(2).
|
||||
const (
|
||||
CSIGNAL = 0xff
|
||||
|
||||
CLONE_VM = 0x100
|
||||
CLONE_FS = 0x200
|
||||
CLONE_FILES = 0x400
|
||||
CLONE_SIGHAND = 0x800
|
||||
CLONE_PIDFD = 0x1000
|
||||
CLONE_PTRACE = 0x2000
|
||||
CLONE_VFORK = 0x4000
|
||||
CLONE_PARENT = 0x8000
|
||||
CLONE_THREAD = 0x10000
|
||||
CLONE_NEWNS = 0x20000
|
||||
CLONE_SYSVSEM = 0x40000
|
||||
CLONE_SETTLS = 0x80000
|
||||
CLONE_PARENT_SETTID = 0x100000
|
||||
CLONE_CHILD_CLEARTID = 0x200000
|
||||
CLONE_DETACHED = 0x400000
|
||||
CLONE_UNTRACED = 0x800000
|
||||
CLONE_CHILD_SETTID = 0x1000000
|
||||
CLONE_NEWCGROUP = 0x2000000
|
||||
CLONE_NEWUTS = 0x4000000
|
||||
CLONE_NEWIPC = 0x8000000
|
||||
CLONE_NEWUSER = 0x10000000
|
||||
CLONE_NEWPID = 0x20000000
|
||||
CLONE_NEWNET = 0x40000000
|
||||
CLONE_IO = 0x80000000
|
||||
|
||||
// Only passable via clone3(2).
|
||||
CLONE_CLEAR_SIGHAND = 0x100000000
|
||||
CLONE_INTO_CGROUP = 0x200000000
|
||||
|
||||
// Sizeof first published struct.
|
||||
CLONE_ARGS_SIZE_VER0 = 64
|
||||
// Sizeof third published struct.
|
||||
CLONE_ARGS_SIZE_VER2 = 88
|
||||
)
|
||||
|
||||
// CloneArgs is struct clone_args, from include/uapi/linux/sched.h.
|
||||
//
|
||||
// +marshal
|
||||
type CloneArgs struct {
|
||||
Flags uint64
|
||||
Pidfd uint64
|
||||
ChildTID uint64
|
||||
ParentTID uint64
|
||||
ExitSignal uint64
|
||||
Stack uint64
|
||||
StackSize uint64
|
||||
TLS uint64
|
||||
SetTID uint64
|
||||
SetTIDSize uint64
|
||||
Cgroup uint64
|
||||
}
|
||||
36
pkg/abi/linux/context.go
Normal file
36
pkg/abi/linux/context.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2021 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"github.com/sagernet/gvisor/pkg/context"
|
||||
)
|
||||
|
||||
// contextID is the linux package's type for context.Context.Value keys.
|
||||
type contextID int
|
||||
|
||||
const (
|
||||
// CtxSignalNoInfoFunc is a Context.Value key for a function to send signals.
|
||||
CtxSignalNoInfoFunc contextID = iota
|
||||
)
|
||||
|
||||
// SignalNoInfoFuncFromContext returns a callback function that can be used to send a
|
||||
// signal to the given context.
|
||||
func SignalNoInfoFuncFromContext(ctx context.Context) func(Signal) error {
|
||||
if f := ctx.Value(CtxSignalNoInfoFunc); f != nil {
|
||||
return f.(func(Signal) error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
72
pkg/abi/linux/dev.go
Normal file
72
pkg/abi/linux/dev.go
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// MakeDeviceID encodes a major and minor device number into a single device ID.
|
||||
//
|
||||
// Format (see linux/kdev_t.h:new_encode_dev):
|
||||
//
|
||||
// Bits 7:0 - minor bits 7:0
|
||||
// Bits 19:8 - major bits 11:0
|
||||
// Bits 31:20 - minor bits 19:8
|
||||
func MakeDeviceID(major uint16, minor uint32) uint32 {
|
||||
return (minor & 0xff) | ((uint32(major) & 0xfff) << 8) | ((minor >> 8) << 20)
|
||||
}
|
||||
|
||||
// DecodeDeviceID decodes a device ID into major and minor device numbers.
|
||||
func DecodeDeviceID(rdev uint32) (uint16, uint32) {
|
||||
major := uint16((rdev >> 8) & 0xfff)
|
||||
minor := (rdev & 0xff) | ((rdev >> 20) << 8)
|
||||
return major, minor
|
||||
}
|
||||
|
||||
// Character device IDs.
|
||||
//
|
||||
// See Documentations/devices.txt and uapi/linux/major.h.
|
||||
const (
|
||||
// UNNAMED_MAJOR is the major device number for "unnamed" devices, whose
|
||||
// minor numbers are dynamically allocated by the kernel.
|
||||
UNNAMED_MAJOR = 0
|
||||
|
||||
// MEM_MAJOR is the major device number for "memory" character devices.
|
||||
MEM_MAJOR = 1
|
||||
|
||||
// TTYAUX_MAJOR is the major device number for alternate TTY devices.
|
||||
TTYAUX_MAJOR = 5
|
||||
|
||||
// MISC_MAJOR is the major device number for non-serial mice, misc feature
|
||||
// devices.
|
||||
MISC_MAJOR = 10
|
||||
|
||||
// UNIX98_PTY_MASTER_MAJOR is the initial major device number for
|
||||
// Unix98 PTY masters.
|
||||
UNIX98_PTY_MASTER_MAJOR = 128
|
||||
|
||||
// UNIX98_PTY_REPLICA_MAJOR is the initial major device number for
|
||||
// Unix98 PTY replicas.
|
||||
UNIX98_PTY_REPLICA_MAJOR = 136
|
||||
)
|
||||
|
||||
// Minor device numbers for TTYAUX_MAJOR.
|
||||
const (
|
||||
// PTMX_MINOR is the minor device number for /dev/ptmx.
|
||||
PTMX_MINOR = 2
|
||||
)
|
||||
|
||||
// from Linux include/drm/drm_accel.h
|
||||
const (
|
||||
// ACCEL_MAJOR is the major device number for compute accelerator devices.
|
||||
ACCEL_MAJOR = 121
|
||||
)
|
||||
158
pkg/abi/linux/elf.go
Normal file
158
pkg/abi/linux/elf.go
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Linux auxiliary vector entry types.
|
||||
const (
|
||||
// AT_NULL is the end of the auxiliary vector.
|
||||
AT_NULL = 0
|
||||
|
||||
// AT_IGNORE should be ignored.
|
||||
AT_IGNORE = 1
|
||||
|
||||
// AT_EXECFD is the file descriptor of the program.
|
||||
AT_EXECFD = 2
|
||||
|
||||
// AT_PHDR points to the program headers.
|
||||
AT_PHDR = 3
|
||||
|
||||
// AT_PHENT is the size of a program header entry.
|
||||
AT_PHENT = 4
|
||||
|
||||
// AT_PHNUM is the number of program headers.
|
||||
AT_PHNUM = 5
|
||||
|
||||
// AT_PAGESZ is the system page size.
|
||||
AT_PAGESZ = 6
|
||||
|
||||
// AT_BASE is the base address of the interpreter.
|
||||
AT_BASE = 7
|
||||
|
||||
// AT_FLAGS are flags.
|
||||
AT_FLAGS = 8
|
||||
|
||||
// AT_ENTRY is the program entry point.
|
||||
AT_ENTRY = 9
|
||||
|
||||
// AT_NOTELF indicates that the program is not an ELF binary.
|
||||
AT_NOTELF = 10
|
||||
|
||||
// AT_UID is the real UID.
|
||||
AT_UID = 11
|
||||
|
||||
// AT_EUID is the effective UID.
|
||||
AT_EUID = 12
|
||||
|
||||
// AT_GID is the real GID.
|
||||
AT_GID = 13
|
||||
|
||||
// AT_EGID is the effective GID.
|
||||
AT_EGID = 14
|
||||
|
||||
// AT_PLATFORM is a string identifying the CPU.
|
||||
AT_PLATFORM = 15
|
||||
|
||||
// AT_HWCAP are arch-dependent CPU capabilities.
|
||||
AT_HWCAP = 16
|
||||
|
||||
// AT_CLKTCK is the frequency used by times(2).
|
||||
AT_CLKTCK = 17
|
||||
|
||||
// AT_SECURE indicate secure mode.
|
||||
AT_SECURE = 23
|
||||
|
||||
// AT_BASE_PLATFORM is a string identifying the "real" platform. It may
|
||||
// differ from AT_PLATFORM.
|
||||
AT_BASE_PLATFORM = 24
|
||||
|
||||
// AT_RANDOM points to 16-bytes of random data.
|
||||
AT_RANDOM = 25
|
||||
|
||||
// AT_HWCAP2 is an extension of AT_HWCAP.
|
||||
AT_HWCAP2 = 26
|
||||
|
||||
// AT_EXECFN is the path used to execute the program.
|
||||
AT_EXECFN = 31
|
||||
|
||||
// AT_SYSINFO_EHDR is the address of the VDSO.
|
||||
AT_SYSINFO_EHDR = 33
|
||||
)
|
||||
|
||||
// ELF ET_CORE and ptrace GETREGSET/SETREGSET register set types.
|
||||
//
|
||||
// See include/uapi/linux/elf.h.
|
||||
const (
|
||||
// NT_PRSTATUS is for general purpose register.
|
||||
NT_PRSTATUS = 0x1
|
||||
|
||||
// NT_PRFPREG is for float point register.
|
||||
NT_PRFPREG = 0x2
|
||||
|
||||
// NT_X86_XSTATE is for x86 extended state using xsave.
|
||||
NT_X86_XSTATE = 0x202
|
||||
|
||||
// NT_ARM_TLS is for ARM TLS register.
|
||||
NT_ARM_TLS = 0x401
|
||||
)
|
||||
|
||||
// ElfHeader64 is the ELF64 file header.
|
||||
//
|
||||
// +marshal
|
||||
type ElfHeader64 struct {
|
||||
Ident [16]byte // File identification.
|
||||
Type uint16 // File type.
|
||||
Machine uint16 // Machine architecture.
|
||||
Version uint32 // ELF format version.
|
||||
Entry uint64 // Entry point.
|
||||
Phoff uint64 // Program header file offset.
|
||||
Shoff uint64 // Section header file offset.
|
||||
Flags uint32 // Architecture-specific flags.
|
||||
Ehsize uint16 // Size of ELF header in bytes.
|
||||
Phentsize uint16 // Size of program header entry.
|
||||
Phnum uint16 // Number of program header entries.
|
||||
Shentsize uint16 // Size of section header entry.
|
||||
Shnum uint16 // Number of section header entries.
|
||||
Shstrndx uint16 // Section name strings section.
|
||||
}
|
||||
|
||||
// ElfSection64 is the ELF64 Section header.
|
||||
//
|
||||
// +marshal
|
||||
type ElfSection64 struct {
|
||||
Name uint32 // Section name (index into the section header string table).
|
||||
Type uint32 // Section type.
|
||||
Flags uint64 // Section flags.
|
||||
Addr uint64 // Address in memory image.
|
||||
Off uint64 // Offset in file.
|
||||
Size uint64 // Size in bytes.
|
||||
Link uint32 // Index of a related section.
|
||||
Info uint32 // Depends on section type.
|
||||
Addralign uint64 // Alignment in bytes.
|
||||
Entsize uint64 // Size of each entry in section.
|
||||
}
|
||||
|
||||
// ElfProg64 is the ELF64 Program header.
|
||||
//
|
||||
// +marshal
|
||||
type ElfProg64 struct {
|
||||
Type uint32 // Entry type.
|
||||
Flags uint32 // Access permission flags.
|
||||
Off uint64 // File offset of contents.
|
||||
Vaddr uint64 // Virtual address in memory image.
|
||||
Paddr uint64 // Physical address (not used).
|
||||
Filesz uint64 // Size of contents in file.
|
||||
Memsz uint64 // Size of contents in memory.
|
||||
Align uint64 // Alignment in memory and file.
|
||||
}
|
||||
58
pkg/abi/linux/epoll.go
Normal file
58
pkg/abi/linux/epoll.go
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Event masks.
|
||||
const (
|
||||
EPOLLIN = 0x1
|
||||
EPOLLPRI = 0x2
|
||||
EPOLLOUT = 0x4
|
||||
EPOLLERR = 0x8
|
||||
EPOLLHUP = 0x10
|
||||
EPOLLRDNORM = 0x40
|
||||
EPOLLRDBAND = 0x80
|
||||
EPOLLWRNORM = 0x100
|
||||
EPOLLWRBAND = 0x200
|
||||
EPOLLMSG = 0x400
|
||||
EPOLLRDHUP = 0x2000
|
||||
)
|
||||
|
||||
// Per-file descriptor flags.
|
||||
const (
|
||||
EPOLLEXCLUSIVE = 1 << 28
|
||||
EPOLLWAKEUP = 1 << 29
|
||||
EPOLLONESHOT = 1 << 30
|
||||
EPOLLET = 1 << 31
|
||||
|
||||
// EP_PRIVATE_BITS is fs/eventpoll.c:EP_PRIVATE_BITS, the set of all bits
|
||||
// in an epoll event mask that correspond to flags rather than I/O events.
|
||||
EP_PRIVATE_BITS = EPOLLEXCLUSIVE | EPOLLWAKEUP | EPOLLONESHOT | EPOLLET
|
||||
)
|
||||
|
||||
// Operation flags.
|
||||
const (
|
||||
EPOLL_CLOEXEC = 0x80000
|
||||
EPOLL_NONBLOCK = 0x800
|
||||
)
|
||||
|
||||
// Control operations.
|
||||
const (
|
||||
EPOLL_CTL_ADD = 0x1
|
||||
EPOLL_CTL_DEL = 0x2
|
||||
EPOLL_CTL_MOD = 0x3
|
||||
)
|
||||
|
||||
// SizeOfEpollEvent is the size of EpollEvent struct.
|
||||
var SizeOfEpollEvent = (*EpollEvent)(nil).SizeBytes()
|
||||
30
pkg/abi/linux/epoll_amd64.go
Normal file
30
pkg/abi/linux/epoll_amd64.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build amd64
|
||||
// +build amd64
|
||||
|
||||
package linux
|
||||
|
||||
// EpollEvent is equivalent to struct epoll_event from epoll(2).
|
||||
//
|
||||
// +marshal slice:EpollEventSlice
|
||||
type EpollEvent struct {
|
||||
Events uint32
|
||||
// Linux makes struct epoll_event::data a __u64. We represent it as
|
||||
// [2]int32 because, on amd64, Linux also makes struct epoll_event
|
||||
// __attribute__((packed)), such that there is no padding between Events
|
||||
// and Data.
|
||||
Data [2]int32
|
||||
}
|
||||
29
pkg/abi/linux/epoll_arm64.go
Normal file
29
pkg/abi/linux/epoll_arm64.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build arm64
|
||||
// +build arm64
|
||||
|
||||
package linux
|
||||
|
||||
// EpollEvent is equivalent to struct epoll_event from epoll(2).
|
||||
//
|
||||
// +marshal slice:EpollEventSlice
|
||||
type EpollEvent struct {
|
||||
Events uint32
|
||||
// Linux makes struct epoll_event a __u64, necessitating 4 bytes of padding
|
||||
// here.
|
||||
_ int32
|
||||
Data [2]int32
|
||||
}
|
||||
187
pkg/abi/linux/errno/errno.go
Normal file
187
pkg/abi/linux/errno/errno.go
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package errno holds errno codes for abi/linux.
|
||||
package errno
|
||||
|
||||
// Errno represents a Linux errno value.
|
||||
type Errno uint32
|
||||
|
||||
// Errno values from include/uapi/asm-generic/errno-base.h.
|
||||
const (
|
||||
NOERRNO = iota
|
||||
EPERM
|
||||
ENOENT
|
||||
ESRCH
|
||||
EINTR
|
||||
EIO
|
||||
ENXIO
|
||||
E2BIG
|
||||
ENOEXEC
|
||||
EBADF
|
||||
ECHILD // 10
|
||||
EAGAIN
|
||||
ENOMEM
|
||||
EACCES
|
||||
EFAULT
|
||||
ENOTBLK
|
||||
EBUSY
|
||||
EEXIST
|
||||
EXDEV
|
||||
ENODEV
|
||||
ENOTDIR // 20
|
||||
EISDIR
|
||||
EINVAL
|
||||
ENFILE
|
||||
EMFILE
|
||||
ENOTTY
|
||||
ETXTBSY
|
||||
EFBIG
|
||||
ENOSPC
|
||||
ESPIPE
|
||||
EROFS // 30
|
||||
EMLINK
|
||||
EPIPE
|
||||
EDOM
|
||||
ERANGE
|
||||
// Errno values from include/uapi/asm-generic/errno.h.
|
||||
EDEADLK
|
||||
ENAMETOOLONG
|
||||
ENOLCK
|
||||
ENOSYS
|
||||
ENOTEMPTY
|
||||
ELOOP // 40
|
||||
_ // Skip for EWOULDBLOCK = EAGAIN.
|
||||
ENOMSG // 42
|
||||
EIDRM
|
||||
ECHRNG
|
||||
EL2NSYNC
|
||||
EL3HLT
|
||||
EL3RST
|
||||
ELNRNG
|
||||
EUNATCH
|
||||
ENOCSI
|
||||
EL2HLT // 50
|
||||
EBADE
|
||||
EBADR
|
||||
EXFULL
|
||||
ENOANO
|
||||
EBADRQC
|
||||
EBADSLT
|
||||
_ // Skip for EDEADLOCK = EDEADLK.
|
||||
EBFONT
|
||||
ENOSTR // 60
|
||||
ENODATA
|
||||
ETIME
|
||||
ENOSR
|
||||
ENONET
|
||||
ENOPKG
|
||||
EREMOTE
|
||||
ENOLINK
|
||||
EADV
|
||||
ESRMNT
|
||||
ECOMM // 70
|
||||
EPROTO
|
||||
EMULTIHOP
|
||||
EDOTDOT
|
||||
EBADMSG
|
||||
EOVERFLOW
|
||||
ENOTUNIQ
|
||||
EBADFD
|
||||
EREMCHG
|
||||
ELIBACC
|
||||
ELIBBAD // 80
|
||||
ELIBSCN
|
||||
ELIBMAX
|
||||
ELIBEXEC
|
||||
EILSEQ
|
||||
ERESTART
|
||||
ESTRPIPE
|
||||
EUSERS
|
||||
ENOTSOCK
|
||||
EDESTADDRREQ
|
||||
EMSGSIZE // 90
|
||||
EPROTOTYPE
|
||||
ENOPROTOOPT
|
||||
EPROTONOSUPPORT
|
||||
ESOCKTNOSUPPORT
|
||||
EOPNOTSUPP
|
||||
EPFNOSUPPORT
|
||||
EAFNOSUPPORT
|
||||
EADDRINUSE
|
||||
EADDRNOTAVAIL
|
||||
ENETDOWN // 100
|
||||
ENETUNREACH
|
||||
ENETRESET
|
||||
ECONNABORTED
|
||||
ECONNRESET
|
||||
ENOBUFS
|
||||
EISCONN
|
||||
ENOTCONN
|
||||
ESHUTDOWN
|
||||
ETOOMANYREFS
|
||||
ETIMEDOUT // 110
|
||||
ECONNREFUSED
|
||||
EHOSTDOWN
|
||||
EHOSTUNREACH
|
||||
EALREADY
|
||||
EINPROGRESS
|
||||
ESTALE
|
||||
EUCLEAN
|
||||
ENOTNAM
|
||||
ENAVAIL
|
||||
EISNAM // 120
|
||||
EREMOTEIO
|
||||
EDQUOT
|
||||
ENOMEDIUM
|
||||
EMEDIUMTYPE
|
||||
ECANCELED
|
||||
ENOKEY
|
||||
EKEYEXPIRED
|
||||
EKEYREVOKED
|
||||
EKEYREJECTED
|
||||
EOWNERDEAD // 130
|
||||
ENOTRECOVERABLE
|
||||
ERFKILL
|
||||
EHWPOISON
|
||||
)
|
||||
|
||||
// errnos derived from other errnos.
|
||||
const (
|
||||
EWOULDBLOCK = EAGAIN
|
||||
EDEADLOCK = EDEADLK
|
||||
)
|
||||
|
||||
// errnos for internal errors.
|
||||
const (
|
||||
// ERESTARTSYS is returned by an interrupted syscall to indicate that it
|
||||
// should be converted to EINTR if interrupted by a signal delivered to a
|
||||
// user handler without SA_RESTART set, and restarted otherwise.
|
||||
ERESTARTSYS = 512
|
||||
|
||||
// ERESTARTNOINTR is returned by an interrupted syscall to indicate that it
|
||||
// should always be restarted.
|
||||
ERESTARTNOINTR = 513
|
||||
|
||||
// ERESTARTNOHAND is returned by an interrupted syscall to indicate that it
|
||||
// should be converted to EINTR if interrupted by a signal delivered to a
|
||||
// user handler, and restarted otherwise.
|
||||
ERESTARTNOHAND = 514
|
||||
|
||||
// ERESTART_RESTARTBLOCK is returned by an interrupted syscall to indicate
|
||||
// that it should be restarted using a custom function. The interrupted
|
||||
// syscall must register a custom restart function by calling
|
||||
// Task.SetRestartSyscallFn.
|
||||
ERESTART_RESTARTBLOCK = 516
|
||||
)
|
||||
3
pkg/abi/linux/errno/errno_state_autogen.go
Normal file
3
pkg/abi/linux/errno/errno_state_autogen.go
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// automatically generated by stateify.
|
||||
|
||||
package errno
|
||||
93
pkg/abi/linux/errqueue.go
Normal file
93
pkg/abi/linux/errqueue.go
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"github.com/sagernet/gvisor/pkg/marshal"
|
||||
)
|
||||
|
||||
// Socket error origin codes as defined in include/uapi/linux/errqueue.h.
|
||||
const (
|
||||
SO_EE_ORIGIN_NONE = 0
|
||||
SO_EE_ORIGIN_LOCAL = 1
|
||||
SO_EE_ORIGIN_ICMP = 2
|
||||
SO_EE_ORIGIN_ICMP6 = 3
|
||||
)
|
||||
|
||||
// SockExtendedErr represents struct sock_extended_err in Linux defined in
|
||||
// include/uapi/linux/errqueue.h.
|
||||
//
|
||||
// +marshal
|
||||
type SockExtendedErr struct {
|
||||
Errno uint32
|
||||
Origin uint8
|
||||
Type uint8
|
||||
Code uint8
|
||||
Pad uint8
|
||||
Info uint32
|
||||
Data uint32
|
||||
}
|
||||
|
||||
// SockErrCMsg represents the IP*_RECVERR control message.
|
||||
type SockErrCMsg interface {
|
||||
marshal.Marshallable
|
||||
|
||||
CMsgLevel() uint32
|
||||
CMsgType() uint32
|
||||
}
|
||||
|
||||
// SockErrCMsgIPv4 is the IP_RECVERR control message used in
|
||||
// recvmsg(MSG_ERRQUEUE) by ipv4 sockets. This is equilavent to `struct errhdr`
|
||||
// defined in net/ipv4/ip_sockglue.c:ip_recv_error().
|
||||
//
|
||||
// +marshal
|
||||
type SockErrCMsgIPv4 struct {
|
||||
SockExtendedErr
|
||||
Offender SockAddrInet
|
||||
}
|
||||
|
||||
var _ SockErrCMsg = (*SockErrCMsgIPv4)(nil)
|
||||
|
||||
// CMsgLevel implements SockErrCMsg.CMsgLevel.
|
||||
func (*SockErrCMsgIPv4) CMsgLevel() uint32 {
|
||||
return SOL_IP
|
||||
}
|
||||
|
||||
// CMsgType implements SockErrCMsg.CMsgType.
|
||||
func (*SockErrCMsgIPv4) CMsgType() uint32 {
|
||||
return IP_RECVERR
|
||||
}
|
||||
|
||||
// SockErrCMsgIPv6 is the IPV6_RECVERR control message used in
|
||||
// recvmsg(MSG_ERRQUEUE) by ipv6 sockets. This is equilavent to `struct errhdr`
|
||||
// defined in net/ipv6/datagram.c:ipv6_recv_error().
|
||||
//
|
||||
// +marshal
|
||||
type SockErrCMsgIPv6 struct {
|
||||
SockExtendedErr
|
||||
Offender SockAddrInet6
|
||||
}
|
||||
|
||||
var _ SockErrCMsg = (*SockErrCMsgIPv6)(nil)
|
||||
|
||||
// CMsgLevel implements SockErrCMsg.CMsgLevel.
|
||||
func (*SockErrCMsgIPv6) CMsgLevel() uint32 {
|
||||
return SOL_IPV6
|
||||
}
|
||||
|
||||
// CMsgType implements SockErrCMsg.CMsgType.
|
||||
func (*SockErrCMsgIPv6) CMsgType() uint32 {
|
||||
return IPV6_RECVERR
|
||||
}
|
||||
22
pkg/abi/linux/eventfd.go
Normal file
22
pkg/abi/linux/eventfd.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Constants for eventfd2(2).
|
||||
const (
|
||||
EFD_SEMAPHORE = 0x1
|
||||
EFD_CLOEXEC = O_CLOEXEC
|
||||
EFD_NONBLOCK = O_NONBLOCK
|
||||
)
|
||||
18
pkg/abi/linux/exec.go
Normal file
18
pkg/abi/linux/exec.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// TASK_COMM_LEN is the task command name length.
|
||||
const TASK_COMM_LEN = 16
|
||||
25
pkg/abi/linux/fadvise.go
Normal file
25
pkg/abi/linux/fadvise.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Fadvise constants.
|
||||
const (
|
||||
POSIX_FADV_NORMAL = 0
|
||||
POSIX_FADV_RANDOM = 1
|
||||
POSIX_FADV_SEQUENTIAL = 2
|
||||
POSIX_FADV_WILLNEED = 3
|
||||
POSIX_FADV_DONTNEED = 4
|
||||
POSIX_FADV_NOREUSE = 5
|
||||
)
|
||||
79
pkg/abi/linux/fcntl.go
Normal file
79
pkg/abi/linux/fcntl.go
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Commands from linux/fcntl.h.
|
||||
const (
|
||||
F_DUPFD = 0
|
||||
F_GETFD = 1
|
||||
F_SETFD = 2
|
||||
F_GETFL = 3
|
||||
F_SETFL = 4
|
||||
F_GETLK = 5
|
||||
F_SETLK = 6
|
||||
F_SETLKW = 7
|
||||
F_SETOWN = 8
|
||||
F_GETOWN = 9
|
||||
F_SETSIG = 10
|
||||
F_GETSIG = 11
|
||||
F_SETOWN_EX = 15
|
||||
F_GETOWN_EX = 16
|
||||
F_OFD_GETLK = 36
|
||||
F_OFD_SETLK = 37
|
||||
F_OFD_SETLKW = 38
|
||||
F_DUPFD_CLOEXEC = 1024 + 6
|
||||
F_SETPIPE_SZ = 1024 + 7
|
||||
F_GETPIPE_SZ = 1024 + 8
|
||||
)
|
||||
|
||||
// Commands for F_SETLK.
|
||||
const (
|
||||
F_RDLCK = 0
|
||||
F_WRLCK = 1
|
||||
F_UNLCK = 2
|
||||
)
|
||||
|
||||
// Flags for fcntl.
|
||||
const (
|
||||
FD_CLOEXEC = 0o0000001
|
||||
)
|
||||
|
||||
// Flock is the lock structure for F_SETLK.
|
||||
//
|
||||
// +marshal
|
||||
type Flock struct {
|
||||
Type int16
|
||||
Whence int16
|
||||
_ [4]byte
|
||||
Start int64
|
||||
Len int64
|
||||
PID int32
|
||||
_ [4]byte
|
||||
}
|
||||
|
||||
// Owner types for F_SETOWN_EX and F_GETOWN_EX.
|
||||
const (
|
||||
F_OWNER_TID = 0
|
||||
F_OWNER_PID = 1
|
||||
F_OWNER_PGRP = 2
|
||||
)
|
||||
|
||||
// FOwnerEx is the owner structure for F_SETOWN_EX and F_GETOWN_EX.
|
||||
//
|
||||
// +marshal
|
||||
type FOwnerEx struct {
|
||||
Type int32
|
||||
PID int32
|
||||
}
|
||||
437
pkg/abi/linux/file.go
Normal file
437
pkg/abi/linux/file.go
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/abi"
|
||||
)
|
||||
|
||||
// Constants for open(2).
|
||||
const (
|
||||
O_ACCMODE = 0o00000003
|
||||
O_RDONLY = 0o00000000
|
||||
O_WRONLY = 0o00000001
|
||||
O_RDWR = 0o00000002
|
||||
O_CREAT = 0o00000100
|
||||
O_EXCL = 0o00000200
|
||||
O_NOCTTY = 0o00000400
|
||||
O_TRUNC = 0o00001000
|
||||
O_APPEND = 0o00002000
|
||||
O_NONBLOCK = 0o00004000
|
||||
O_DSYNC = 0o00010000
|
||||
O_ASYNC = 0o00020000
|
||||
O_NOATIME = 0o01000000
|
||||
O_CLOEXEC = 0o02000000
|
||||
O_SYNC = 0o04000000 // __O_SYNC in Linux
|
||||
O_PATH = 0o10000000
|
||||
O_TMPFILE = 0o20000000 // __O_TMPFILE in Linux
|
||||
)
|
||||
|
||||
// Constants for fstatat(2).
|
||||
const (
|
||||
AT_SYMLINK_NOFOLLOW = 0x100
|
||||
)
|
||||
|
||||
// Constants for mount(2).
|
||||
const (
|
||||
MS_RDONLY = 0x1
|
||||
MS_NOSUID = 0x2
|
||||
MS_NODEV = 0x4
|
||||
MS_NOEXEC = 0x8
|
||||
MS_SYNCHRONOUS = 0x10
|
||||
MS_REMOUNT = 0x20
|
||||
MS_MANDLOCK = 0x40
|
||||
MS_DIRSYNC = 0x80
|
||||
MS_NOATIME = 0x400
|
||||
MS_NODIRATIME = 0x800
|
||||
MS_BIND = 0x1000
|
||||
MS_MOVE = 0x2000
|
||||
MS_REC = 0x4000
|
||||
|
||||
MS_POSIXACL = 0x10000
|
||||
MS_UNBINDABLE = 0x20000
|
||||
MS_PRIVATE = 0x40000
|
||||
MS_SLAVE = 0x80000
|
||||
MS_SHARED = 0x100000
|
||||
MS_RELATIME = 0x200000
|
||||
MS_KERNMOUNT = 0x400000
|
||||
MS_I_VERSION = 0x800000
|
||||
MS_STRICTATIME = 0x1000000
|
||||
|
||||
MS_MGC_VAL = 0xC0ED0000
|
||||
MS_MGC_MSK = 0xffff0000
|
||||
)
|
||||
|
||||
// Constants for umount2(2).
|
||||
const (
|
||||
MNT_FORCE = 0x1
|
||||
MNT_DETACH = 0x2
|
||||
MNT_EXPIRE = 0x4
|
||||
UMOUNT_NOFOLLOW = 0x8
|
||||
)
|
||||
|
||||
// Constants for unlinkat(2).
|
||||
const (
|
||||
AT_REMOVEDIR = 0x200
|
||||
)
|
||||
|
||||
// Constants for linkat(2) and fchownat(2).
|
||||
const (
|
||||
AT_SYMLINK_FOLLOW = 0x400
|
||||
AT_EMPTY_PATH = 0x1000
|
||||
)
|
||||
|
||||
// Constants for faccessat2(2).
|
||||
const (
|
||||
AT_EACCESS = 0x200
|
||||
)
|
||||
|
||||
// Constants for all file-related ...at(2) syscalls.
|
||||
const (
|
||||
AT_FDCWD = -100
|
||||
)
|
||||
|
||||
// Special values for the ns field in utimensat(2).
|
||||
const (
|
||||
UTIME_NOW = ((1 << 30) - 1)
|
||||
UTIME_OMIT = ((1 << 30) - 2)
|
||||
)
|
||||
|
||||
// MaxSymlinkTraversals is the maximum number of links that will be followed by
|
||||
// the kernel to resolve a symlink.
|
||||
const MaxSymlinkTraversals = 40
|
||||
|
||||
// Constants for flock(2).
|
||||
const (
|
||||
LOCK_SH = 1 // shared lock
|
||||
LOCK_EX = 2 // exclusive lock
|
||||
LOCK_NB = 4 // or'd with one of the above to prevent blocking
|
||||
LOCK_UN = 8 // remove lock
|
||||
)
|
||||
|
||||
// Values for mode_t.
|
||||
const (
|
||||
S_IFMT = 0o170000
|
||||
S_IFSOCK = 0o140000
|
||||
S_IFLNK = 0o120000
|
||||
S_IFREG = 0o100000
|
||||
S_IFBLK = 0o60000
|
||||
S_IFDIR = 0o40000
|
||||
S_IFCHR = 0o20000
|
||||
S_IFIFO = 0o10000
|
||||
|
||||
FileTypeMask = S_IFMT
|
||||
ModeSocket = S_IFSOCK
|
||||
ModeSymlink = S_IFLNK
|
||||
ModeRegular = S_IFREG
|
||||
ModeBlockDevice = S_IFBLK
|
||||
ModeDirectory = S_IFDIR
|
||||
ModeCharacterDevice = S_IFCHR
|
||||
ModeNamedPipe = S_IFIFO
|
||||
|
||||
S_ISUID = 0o4000
|
||||
S_ISGID = 0o2000
|
||||
S_ISVTX = 0o1000
|
||||
|
||||
ModeSetUID = S_ISUID
|
||||
ModeSetGID = S_ISGID
|
||||
ModeSticky = S_ISVTX
|
||||
|
||||
ModeUserAll = 0o700
|
||||
ModeUserRead = 0o400
|
||||
ModeUserWrite = 0o200
|
||||
ModeUserExec = 0o100
|
||||
ModeGroupAll = 0o070
|
||||
ModeGroupRead = 0o040
|
||||
ModeGroupWrite = 0o020
|
||||
ModeGroupExec = 0o010
|
||||
ModeOtherAll = 0o007
|
||||
ModeOtherRead = 0o004
|
||||
ModeOtherWrite = 0o002
|
||||
ModeOtherExec = 0o001
|
||||
PermissionsMask = 0o777
|
||||
)
|
||||
|
||||
// Values for linux_dirent64.d_type.
|
||||
const (
|
||||
DT_UNKNOWN = 0
|
||||
DT_FIFO = 1
|
||||
DT_CHR = 2
|
||||
DT_DIR = 4
|
||||
DT_BLK = 6
|
||||
DT_REG = 8
|
||||
DT_LNK = 10
|
||||
DT_SOCK = 12
|
||||
DT_WHT = 14
|
||||
)
|
||||
|
||||
// DirentType are the friendly strings for linux_dirent64.d_type.
|
||||
var DirentType = abi.ValueSet{
|
||||
DT_UNKNOWN: "DT_UNKNOWN",
|
||||
DT_FIFO: "DT_FIFO",
|
||||
DT_CHR: "DT_CHR",
|
||||
DT_DIR: "DT_DIR",
|
||||
DT_BLK: "DT_BLK",
|
||||
DT_REG: "DT_REG",
|
||||
DT_LNK: "DT_LNK",
|
||||
DT_SOCK: "DT_SOCK",
|
||||
DT_WHT: "DT_WHT",
|
||||
}
|
||||
|
||||
// Values for fs on-disk file types.
|
||||
const (
|
||||
FT_UNKNOWN = 0
|
||||
FT_REG_FILE = 1
|
||||
FT_DIR = 2
|
||||
FT_CHRDEV = 3
|
||||
FT_BLKDEV = 4
|
||||
FT_FIFO = 5
|
||||
FT_SOCK = 6
|
||||
FT_SYMLINK = 7
|
||||
FT_MAX = 8
|
||||
)
|
||||
|
||||
// Conversion from fs on-disk file type to dirent type.
|
||||
var direntTypeByFileType = [FT_MAX]uint8{
|
||||
FT_UNKNOWN: DT_UNKNOWN,
|
||||
FT_REG_FILE: DT_REG,
|
||||
FT_DIR: DT_DIR,
|
||||
FT_CHRDEV: DT_CHR,
|
||||
FT_BLKDEV: DT_BLK,
|
||||
FT_FIFO: DT_FIFO,
|
||||
FT_SOCK: DT_SOCK,
|
||||
FT_SYMLINK: DT_LNK,
|
||||
}
|
||||
|
||||
// FileTypeToDirentType converts the on-disk file type (FT_*) to the directory
|
||||
// entry type (DT_*).
|
||||
func FileTypeToDirentType(filetype uint8) uint8 {
|
||||
if filetype >= FT_MAX {
|
||||
return DT_UNKNOWN
|
||||
}
|
||||
return direntTypeByFileType[filetype]
|
||||
}
|
||||
|
||||
// Values for preadv2/pwritev2.
|
||||
const (
|
||||
// NOTE(b/120162627): gVisor does not implement the RWF_HIPRI feature, but
|
||||
// the flag is accepted as a valid flag argument for preadv2/pwritev2 and
|
||||
// silently ignored.
|
||||
RWF_HIPRI = 0x00000001
|
||||
RWF_DSYNC = 0x00000002
|
||||
RWF_SYNC = 0x00000004
|
||||
RWF_VALID = RWF_HIPRI | RWF_DSYNC | RWF_SYNC
|
||||
)
|
||||
|
||||
// SizeOfStat is the size of a Stat struct.
|
||||
var SizeOfStat = (*Stat)(nil).SizeBytes()
|
||||
|
||||
// Flags for statx.
|
||||
const (
|
||||
AT_NO_AUTOMOUNT = 0x800
|
||||
AT_STATX_SYNC_TYPE = 0x6000
|
||||
AT_STATX_SYNC_AS_STAT = 0x0000
|
||||
AT_STATX_FORCE_SYNC = 0x2000
|
||||
AT_STATX_DONT_SYNC = 0x4000
|
||||
)
|
||||
|
||||
// Mask values for statx.
|
||||
const (
|
||||
STATX_TYPE = 0x00000001
|
||||
STATX_MODE = 0x00000002
|
||||
STATX_NLINK = 0x00000004
|
||||
STATX_UID = 0x00000008
|
||||
STATX_GID = 0x00000010
|
||||
STATX_ATIME = 0x00000020
|
||||
STATX_MTIME = 0x00000040
|
||||
STATX_CTIME = 0x00000080
|
||||
STATX_INO = 0x00000100
|
||||
STATX_SIZE = 0x00000200
|
||||
STATX_BLOCKS = 0x00000400
|
||||
STATX_BASIC_STATS = 0x000007ff
|
||||
STATX_BTIME = 0x00000800
|
||||
STATX_ALL = 0x00000fff
|
||||
STATX__RESERVED = 0x80000000
|
||||
)
|
||||
|
||||
// Bitmasks for Statx.Attributes and Statx.AttributesMask, from
|
||||
// include/uapi/linux/stat.h.
|
||||
const (
|
||||
STATX_ATTR_COMPRESSED = 0x00000004
|
||||
STATX_ATTR_IMMUTABLE = 0x00000010
|
||||
STATX_ATTR_APPEND = 0x00000020
|
||||
STATX_ATTR_NODUMP = 0x00000040
|
||||
STATX_ATTR_ENCRYPTED = 0x00000800
|
||||
STATX_ATTR_AUTOMOUNT = 0x00001000
|
||||
)
|
||||
|
||||
// Statx represents struct statx.
|
||||
//
|
||||
// +marshal boundCheck slice:StatxSlice
|
||||
type Statx struct {
|
||||
Mask uint32
|
||||
Blksize uint32
|
||||
Attributes uint64
|
||||
Nlink uint32
|
||||
UID uint32
|
||||
GID uint32
|
||||
Mode uint16
|
||||
_ uint16
|
||||
Ino uint64
|
||||
Size uint64
|
||||
Blocks uint64
|
||||
AttributesMask uint64
|
||||
Atime StatxTimestamp
|
||||
Btime StatxTimestamp
|
||||
Ctime StatxTimestamp
|
||||
Mtime StatxTimestamp
|
||||
RdevMajor uint32
|
||||
RdevMinor uint32
|
||||
DevMajor uint32
|
||||
DevMinor uint32
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.String.
|
||||
func (s *Statx) String() string {
|
||||
return fmt.Sprintf("Statx{Mask: %#x, Mode: %s, UID: %d, GID: %d, Ino: %d, DevMajor: %d, DevMinor: %d, Size: %d, Blocks: %d, Blksize: %d, Nlink: %d, Atime: %s, Btime: %s, Ctime: %s, Mtime: %s, Attributes: %d, AttributesMask: %d, RdevMajor: %d, RdevMinor: %d}",
|
||||
s.Mask, FileMode(s.Mode), s.UID, s.GID, s.Ino, s.DevMajor, s.DevMinor, s.Size, s.Blocks, s.Blksize, s.Nlink, s.Atime.ToTime(), s.Btime.ToTime(), s.Ctime.ToTime(), s.Mtime.ToTime(), s.Attributes, s.AttributesMask, s.RdevMajor, s.RdevMinor)
|
||||
}
|
||||
|
||||
// SizeOfStatx is the size of a Statx struct.
|
||||
var SizeOfStatx = (*Statx)(nil).SizeBytes()
|
||||
|
||||
// FileMode represents a mode_t.
|
||||
//
|
||||
// +marshal
|
||||
type FileMode uint16
|
||||
|
||||
// Permissions returns just the permission bits.
|
||||
func (m FileMode) Permissions() FileMode {
|
||||
return m & PermissionsMask
|
||||
}
|
||||
|
||||
// FileType returns just the file type bits.
|
||||
func (m FileMode) FileType() FileMode {
|
||||
return m & FileTypeMask
|
||||
}
|
||||
|
||||
// ExtraBits returns everything but the file type and permission bits.
|
||||
func (m FileMode) ExtraBits() FileMode {
|
||||
return m &^ (PermissionsMask | FileTypeMask)
|
||||
}
|
||||
|
||||
// IsDir returns true if file type represents a directory.
|
||||
func (m FileMode) IsDir() bool {
|
||||
return m.FileType() == S_IFDIR
|
||||
}
|
||||
|
||||
// String returns a string representation of m.
|
||||
func (m FileMode) String() string {
|
||||
var s []string
|
||||
if ft := m.FileType(); ft != 0 {
|
||||
s = append(s, fileType.Parse(uint64(ft)))
|
||||
}
|
||||
if eb := m.ExtraBits(); eb != 0 {
|
||||
s = append(s, modeExtraBits.Parse(uint64(eb)))
|
||||
}
|
||||
s = append(s, fmt.Sprintf("0o%o", m.Permissions()))
|
||||
return strings.Join(s, "|")
|
||||
}
|
||||
|
||||
// DirentType maps file types to dirent types appropriate for (struct
|
||||
// dirent)::d_type.
|
||||
func (m FileMode) DirentType() uint8 {
|
||||
switch m.FileType() {
|
||||
case ModeSocket:
|
||||
return DT_SOCK
|
||||
case ModeSymlink:
|
||||
return DT_LNK
|
||||
case ModeRegular:
|
||||
return DT_REG
|
||||
case ModeBlockDevice:
|
||||
return DT_BLK
|
||||
case ModeDirectory:
|
||||
return DT_DIR
|
||||
case ModeCharacterDevice:
|
||||
return DT_CHR
|
||||
case ModeNamedPipe:
|
||||
return DT_FIFO
|
||||
default:
|
||||
return DT_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
var modeExtraBits = abi.FlagSet{
|
||||
{
|
||||
Flag: ModeSetUID,
|
||||
Name: "S_ISUID",
|
||||
},
|
||||
{
|
||||
Flag: ModeSetGID,
|
||||
Name: "S_ISGID",
|
||||
},
|
||||
{
|
||||
Flag: ModeSticky,
|
||||
Name: "S_ISVTX",
|
||||
},
|
||||
}
|
||||
|
||||
var fileType = abi.ValueSet{
|
||||
ModeSocket: "S_IFSOCK",
|
||||
ModeSymlink: "S_IFLINK",
|
||||
ModeRegular: "S_IFREG",
|
||||
ModeBlockDevice: "S_IFBLK",
|
||||
ModeDirectory: "S_IFDIR",
|
||||
ModeCharacterDevice: "S_IFCHR",
|
||||
ModeNamedPipe: "S_IFIFO",
|
||||
}
|
||||
|
||||
// Constants for memfd_create(2). Source: include/uapi/linux/memfd.h
|
||||
const (
|
||||
MFD_CLOEXEC = 0x0001
|
||||
MFD_ALLOW_SEALING = 0x0002
|
||||
)
|
||||
|
||||
// Constants related to file seals. Source: include/uapi/{asm-generic,linux}/fcntl.h
|
||||
const (
|
||||
F_LINUX_SPECIFIC_BASE = 1024
|
||||
F_ADD_SEALS = F_LINUX_SPECIFIC_BASE + 9
|
||||
F_GET_SEALS = F_LINUX_SPECIFIC_BASE + 10
|
||||
|
||||
F_SEAL_SEAL = 0x0001 // Prevent further seals from being set.
|
||||
F_SEAL_SHRINK = 0x0002 // Prevent file from shrinking.
|
||||
F_SEAL_GROW = 0x0004 // Prevent file from growing.
|
||||
F_SEAL_WRITE = 0x0008 // Prevent writes.
|
||||
)
|
||||
|
||||
// Constants related to fallocate(2). Source: include/uapi/linux/falloc.h
|
||||
const (
|
||||
FALLOC_FL_KEEP_SIZE = 0x01
|
||||
FALLOC_FL_PUNCH_HOLE = 0x02
|
||||
FALLOC_FL_NO_HIDE_STALE = 0x04
|
||||
FALLOC_FL_COLLAPSE_RANGE = 0x08
|
||||
FALLOC_FL_ZERO_RANGE = 0x10
|
||||
FALLOC_FL_INSERT_RANGE = 0x20
|
||||
FALLOC_FL_UNSHARE_RANGE = 0x40
|
||||
)
|
||||
|
||||
// Constants related to close_range(2). Source: /include/uapi/linux/close_range.h
|
||||
const (
|
||||
CLOSE_RANGE_UNSHARE = uint32(1 << 1)
|
||||
CLOSE_RANGE_CLOEXEC = uint32(1 << 2)
|
||||
)
|
||||
47
pkg/abi/linux/file_amd64.go
Normal file
47
pkg/abi/linux/file_amd64.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build amd64
|
||||
// +build amd64
|
||||
|
||||
package linux
|
||||
|
||||
// Constants for open(2).
|
||||
const (
|
||||
O_DIRECT = 0o00040000
|
||||
O_LARGEFILE = 0o00100000
|
||||
O_DIRECTORY = 0o00200000
|
||||
O_NOFOLLOW = 0o00400000
|
||||
)
|
||||
|
||||
// Stat represents struct stat.
|
||||
//
|
||||
// +marshal
|
||||
type Stat struct {
|
||||
Dev uint64
|
||||
Ino uint64
|
||||
Nlink uint64
|
||||
Mode uint32
|
||||
UID uint32
|
||||
GID uint32
|
||||
_ int32
|
||||
Rdev uint64
|
||||
Size int64
|
||||
Blksize int64
|
||||
Blocks int64
|
||||
ATime Timespec
|
||||
MTime Timespec
|
||||
CTime Timespec
|
||||
_ [3]int64
|
||||
}
|
||||
48
pkg/abi/linux/file_arm64.go
Normal file
48
pkg/abi/linux/file_arm64.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build arm64
|
||||
// +build arm64
|
||||
|
||||
package linux
|
||||
|
||||
// Constants for open(2).
|
||||
const (
|
||||
O_DIRECTORY = 0o00040000
|
||||
O_NOFOLLOW = 0o00100000
|
||||
O_DIRECT = 0o00200000
|
||||
O_LARGEFILE = 0o00400000
|
||||
)
|
||||
|
||||
// Stat represents struct stat.
|
||||
//
|
||||
// +marshal
|
||||
type Stat struct {
|
||||
Dev uint64
|
||||
Ino uint64
|
||||
Mode uint32
|
||||
Nlink uint32
|
||||
UID uint32
|
||||
GID uint32
|
||||
Rdev uint64
|
||||
_ uint64
|
||||
Size int64
|
||||
Blksize int32
|
||||
_ int32
|
||||
Blocks int64
|
||||
ATime Timespec
|
||||
MTime Timespec
|
||||
CTime Timespec
|
||||
_ [2]int32
|
||||
}
|
||||
129
pkg/abi/linux/fs.go
Normal file
129
pkg/abi/linux/fs.go
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Filesystem types used in statfs(2).
|
||||
//
|
||||
// See linux/magic.h.
|
||||
const (
|
||||
ANON_INODE_FS_MAGIC = 0x09041934
|
||||
CGROUP_SUPER_MAGIC = 0x27e0eb
|
||||
DEVPTS_SUPER_MAGIC = 0x00001cd1
|
||||
EXT_SUPER_MAGIC = 0xef53
|
||||
FUSE_SUPER_MAGIC = 0x65735546
|
||||
MQUEUE_MAGIC = 0x19800202
|
||||
NSFS_MAGIC = 0x6e736673
|
||||
OVERLAYFS_SUPER_MAGIC = 0x794c7630
|
||||
PIPEFS_MAGIC = 0x50495045
|
||||
PROC_SUPER_MAGIC = 0x9fa0
|
||||
RAMFS_MAGIC = 0x09041934
|
||||
SOCKFS_MAGIC = 0x534F434B
|
||||
SYSFS_MAGIC = 0x62656572
|
||||
TMPFS_MAGIC = 0x01021994
|
||||
V9FS_MAGIC = 0x01021997
|
||||
)
|
||||
|
||||
// Filesystem path limits, from uapi/linux/limits.h.
|
||||
const (
|
||||
NAME_MAX = 255
|
||||
PATH_MAX = 4096
|
||||
)
|
||||
|
||||
// The bit mask f_flags in struct statfs, from include/linux/statfs.h
|
||||
const (
|
||||
ST_RDONLY = 0x0001
|
||||
ST_NOSUID = 0x0002
|
||||
ST_NODEV = 0x0004
|
||||
ST_NOEXEC = 0x0008
|
||||
ST_SYNCHRONOUS = 0x0010
|
||||
ST_VALID = 0x0020
|
||||
ST_MANDLOCK = 0x0040
|
||||
ST_NOATIME = 0x0400
|
||||
ST_NODIRATIME = 0x0800
|
||||
ST_RELATIME = 0x1000
|
||||
ST_NOSYMFOLLOW = 0x2000
|
||||
)
|
||||
|
||||
// Statfs is struct statfs, from uapi/asm-generic/statfs.h.
|
||||
//
|
||||
// +marshal
|
||||
type Statfs struct {
|
||||
// Type is one of the filesystem magic values, defined above.
|
||||
Type uint64
|
||||
|
||||
// BlockSize is the optimal transfer block size in bytes.
|
||||
BlockSize int64
|
||||
|
||||
// Blocks is the maximum number of data blocks the filesystem may store, in
|
||||
// units of BlockSize.
|
||||
Blocks uint64
|
||||
|
||||
// BlocksFree is the number of free data blocks, in units of BlockSize.
|
||||
BlocksFree uint64
|
||||
|
||||
// BlocksAvailable is the number of data blocks free for use by
|
||||
// unprivileged users, in units of BlockSize.
|
||||
BlocksAvailable uint64
|
||||
|
||||
// Files is the number of used file nodes on the filesystem.
|
||||
Files uint64
|
||||
|
||||
// FileFress is the number of free file nodes on the filesystem.
|
||||
FilesFree uint64
|
||||
|
||||
// FSID is the filesystem ID.
|
||||
FSID [2]int32
|
||||
|
||||
// NameLength is the maximum file name length.
|
||||
NameLength uint64
|
||||
|
||||
// FragmentSize is equivalent to BlockSize.
|
||||
FragmentSize int64
|
||||
|
||||
// Flags is the set of filesystem mount flags.
|
||||
Flags uint64
|
||||
|
||||
// Spare is unused.
|
||||
Spare [4]uint64
|
||||
}
|
||||
|
||||
// Whence argument to lseek(2), from include/uapi/linux/fs.h.
|
||||
const (
|
||||
SEEK_SET = 0
|
||||
SEEK_CUR = 1
|
||||
SEEK_END = 2
|
||||
SEEK_DATA = 3
|
||||
SEEK_HOLE = 4
|
||||
)
|
||||
|
||||
// Sync_file_range flags, from include/uapi/linux/fs.h
|
||||
const (
|
||||
SYNC_FILE_RANGE_WAIT_BEFORE = 1
|
||||
SYNC_FILE_RANGE_WRITE = 2
|
||||
SYNC_FILE_RANGE_WAIT_AFTER = 4
|
||||
)
|
||||
|
||||
// Flag argument to renameat2(2), from include/uapi/linux/fs.h.
|
||||
const (
|
||||
RENAME_NOREPLACE = (1 << 0) // Don't overwrite target.
|
||||
RENAME_EXCHANGE = (1 << 1) // Exchange src and dst.
|
||||
RENAME_WHITEOUT = (1 << 2) // Whiteout src.
|
||||
)
|
||||
|
||||
// Overlayfs constants from include/linux/fs.h.
|
||||
const (
|
||||
WHITEOUT_MODE = 0
|
||||
WHITEOUT_DEV = 0
|
||||
)
|
||||
1139
pkg/abi/linux/fuse.go
Normal file
1139
pkg/abi/linux/fuse.go
Normal file
File diff suppressed because it is too large
Load diff
80
pkg/abi/linux/futex.go
Normal file
80
pkg/abi/linux/futex.go
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// From <linux/futex.h> and <sys/time.h>.
|
||||
// Flags are used in syscall futex(2).
|
||||
const (
|
||||
FUTEX_WAIT = 0
|
||||
FUTEX_WAKE = 1
|
||||
FUTEX_FD = 2
|
||||
FUTEX_REQUEUE = 3
|
||||
FUTEX_CMP_REQUEUE = 4
|
||||
FUTEX_WAKE_OP = 5
|
||||
FUTEX_LOCK_PI = 6
|
||||
FUTEX_UNLOCK_PI = 7
|
||||
FUTEX_TRYLOCK_PI = 8
|
||||
FUTEX_WAIT_BITSET = 9
|
||||
FUTEX_WAKE_BITSET = 10
|
||||
FUTEX_WAIT_REQUEUE_PI = 11
|
||||
FUTEX_CMP_REQUEUE_PI = 12
|
||||
|
||||
FUTEX_PRIVATE_FLAG = 128
|
||||
FUTEX_CLOCK_REALTIME = 256
|
||||
)
|
||||
|
||||
// These are flags are from <linux/futex.h> and are used in FUTEX_WAKE_OP
|
||||
// to define the operations.
|
||||
const (
|
||||
FUTEX_OP_SET = 0
|
||||
FUTEX_OP_ADD = 1
|
||||
FUTEX_OP_OR = 2
|
||||
FUTEX_OP_ANDN = 3
|
||||
FUTEX_OP_XOR = 4
|
||||
FUTEX_OP_OPARG_SHIFT = 8
|
||||
FUTEX_OP_CMP_EQ = 0
|
||||
FUTEX_OP_CMP_NE = 1
|
||||
FUTEX_OP_CMP_LT = 2
|
||||
FUTEX_OP_CMP_LE = 3
|
||||
FUTEX_OP_CMP_GT = 4
|
||||
FUTEX_OP_CMP_GE = 5
|
||||
)
|
||||
|
||||
// FUTEX_TID_MASK is the TID portion of a PI futex word.
|
||||
const FUTEX_TID_MASK = 0x3fffffff
|
||||
|
||||
// Constants used for priority-inheritance futexes.
|
||||
const (
|
||||
FUTEX_WAITERS = 0x80000000
|
||||
FUTEX_OWNER_DIED = 0x40000000
|
||||
)
|
||||
|
||||
// FUTEX_BITSET_MATCH_ANY has all bits set.
|
||||
const FUTEX_BITSET_MATCH_ANY = 0xffffffff
|
||||
|
||||
// ROBUST_LIST_LIMIT protects against a deliberately circular list.
|
||||
const ROBUST_LIST_LIMIT = 2048
|
||||
|
||||
// RobustListHead corresponds to Linux's struct robust_list_head.
|
||||
//
|
||||
// +marshal
|
||||
type RobustListHead struct {
|
||||
List uint64
|
||||
FutexOffset uint64
|
||||
ListOpPending uint64
|
||||
}
|
||||
|
||||
// SizeOfRobustListHead is the size of a RobustListHead struct.
|
||||
var SizeOfRobustListHead = (*RobustListHead)(nil).SizeBytes()
|
||||
97
pkg/abi/linux/inotify.go
Normal file
97
pkg/abi/linux/inotify.go
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Inotify events observable by userspace. These directly correspond to
|
||||
// filesystem operations and there may only be a single of them per inotify
|
||||
// event read from an inotify fd.
|
||||
const (
|
||||
// IN_ACCESS indicates a file was accessed.
|
||||
IN_ACCESS = 0x00000001
|
||||
// IN_MODIFY indicates a file was modified.
|
||||
IN_MODIFY = 0x00000002
|
||||
// IN_ATTRIB indicates a watch target's metadata changed.
|
||||
IN_ATTRIB = 0x00000004
|
||||
// IN_CLOSE_WRITE indicates a writable file was closed.
|
||||
IN_CLOSE_WRITE = 0x00000008
|
||||
// IN_CLOSE_NOWRITE indicates a non-writable file was closed.
|
||||
IN_CLOSE_NOWRITE = 0x00000010
|
||||
// IN_OPEN indicates a file was opened.
|
||||
IN_OPEN = 0x00000020
|
||||
// IN_MOVED_FROM indicates a file was moved from X.
|
||||
IN_MOVED_FROM = 0x00000040
|
||||
// IN_MOVED_TO indicates a file was moved to Y.
|
||||
IN_MOVED_TO = 0x00000080
|
||||
// IN_CREATE indicates a file was created in a watched directory.
|
||||
IN_CREATE = 0x00000100
|
||||
// IN_DELETE indicates a file was deleted in a watched directory.
|
||||
IN_DELETE = 0x00000200
|
||||
// IN_DELETE_SELF indicates a watch target itself was deleted.
|
||||
IN_DELETE_SELF = 0x00000400
|
||||
// IN_MOVE_SELF indicates a watch target itself was moved.
|
||||
IN_MOVE_SELF = 0x00000800
|
||||
// IN_ALL_EVENTS is a mask for all observable userspace events.
|
||||
IN_ALL_EVENTS = 0x00000fff
|
||||
)
|
||||
|
||||
// Inotify control events. These may be present in their own events, or ORed
|
||||
// with other observable events.
|
||||
const (
|
||||
// IN_UNMOUNT indicates the backing filesystem was unmounted.
|
||||
IN_UNMOUNT = 0x00002000
|
||||
// IN_Q_OVERFLOW indicates the event queued overflowed.
|
||||
IN_Q_OVERFLOW = 0x00004000
|
||||
// IN_IGNORED indicates a watch was removed, either implicitly or through
|
||||
// inotify_rm_watch(2).
|
||||
IN_IGNORED = 0x00008000
|
||||
// IN_ISDIR indicates the subject of an event was a directory.
|
||||
IN_ISDIR = 0x40000000
|
||||
)
|
||||
|
||||
// Feature flags for inotify_add_watch(2).
|
||||
const (
|
||||
// IN_ONLYDIR indicates that a path should be watched only if it's a
|
||||
// directory.
|
||||
IN_ONLYDIR = 0x01000000
|
||||
// IN_DONT_FOLLOW indicates that the watch path shouldn't be resolved if
|
||||
// it's a symlink.
|
||||
IN_DONT_FOLLOW = 0x02000000
|
||||
// IN_EXCL_UNLINK indicates events to this watch from unlinked objects
|
||||
// should be filtered out.
|
||||
IN_EXCL_UNLINK = 0x04000000
|
||||
// IN_MASK_ADD indicates the provided mask should be ORed into any existing
|
||||
// watch on the provided path.
|
||||
IN_MASK_ADD = 0x20000000
|
||||
// IN_ONESHOT indicates the watch should be removed after one event.
|
||||
IN_ONESHOT = 0x80000000
|
||||
)
|
||||
|
||||
// Feature flags for inotify_init1(2).
|
||||
const (
|
||||
// IN_CLOEXEC is an alias for O_CLOEXEC. It indicates that the inotify
|
||||
// fd should be closed on exec(2) and friends.
|
||||
IN_CLOEXEC = 0x00080000
|
||||
// IN_NONBLOCK is an alias for O_NONBLOCK. It indicates I/O syscall on the
|
||||
// inotify fd should not block.
|
||||
IN_NONBLOCK = 0x00000800
|
||||
)
|
||||
|
||||
// ALL_INOTIFY_BITS contains all the bits for all possible inotify events. It's
|
||||
// defined in the Linux source at "include/linux/inotify.h".
|
||||
const ALL_INOTIFY_BITS = IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE |
|
||||
IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE |
|
||||
IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_Q_OVERFLOW |
|
||||
IN_IGNORED | IN_ONLYDIR | IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD |
|
||||
IN_ISDIR | IN_ONESHOT
|
||||
186
pkg/abi/linux/ioctl.go
Normal file
186
pkg/abi/linux/ioctl.go
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// ioctl(2) requests provided by asm-generic/ioctls.h
|
||||
//
|
||||
// These are ordered by request number (low byte).
|
||||
const (
|
||||
TCGETS = 0x00005401
|
||||
TCSETS = 0x00005402
|
||||
TCSETSW = 0x00005403
|
||||
TCSETSF = 0x00005404
|
||||
TCSBRK = 0x00005409
|
||||
TIOCEXCL = 0x0000540c
|
||||
TIOCNXCL = 0x0000540d
|
||||
TIOCSCTTY = 0x0000540e
|
||||
TIOCGPGRP = 0x0000540f
|
||||
TIOCSPGRP = 0x00005410
|
||||
TIOCOUTQ = 0x00005411
|
||||
TIOCSTI = 0x00005412
|
||||
TIOCGWINSZ = 0x00005413
|
||||
TIOCSWINSZ = 0x00005414
|
||||
TIOCMGET = 0x00005415
|
||||
TIOCMBIS = 0x00005416
|
||||
TIOCMBIC = 0x00005417
|
||||
TIOCMSET = 0x00005418
|
||||
TIOCINQ = 0x0000541b
|
||||
FIONREAD = TIOCINQ
|
||||
TIOCPKT = 0x00005420
|
||||
FIONBIO = 0x00005421
|
||||
TIOCSETD = 0x00005423
|
||||
TIOCNOTTY = 0x00005422
|
||||
TIOCGETD = 0x00005424
|
||||
TCSBRKP = 0x00005425
|
||||
TIOCSBRK = 0x00005427
|
||||
TIOCCBRK = 0x00005428
|
||||
TIOCGSID = 0x00005429
|
||||
TIOCGPTN = 0x80045430
|
||||
TIOCSPTLCK = 0x40045431
|
||||
TIOCGDEV = 0x80045432
|
||||
TIOCVHANGUP = 0x00005437
|
||||
TIOCGPKT = 0x80045438
|
||||
TCFLSH = 0x0000540b
|
||||
TIOCCONS = 0x0000541d
|
||||
TIOCSSERIAL = 0x0000541f
|
||||
TIOCGEXCL = 0x80045440
|
||||
TIOCGPTPEER = 0x80045441
|
||||
TIOCGICOUNT = 0x0000545d
|
||||
FIONCLEX = 0x00005450
|
||||
FIOCLEX = 0x00005451
|
||||
FIOASYNC = 0x00005452
|
||||
FIOSETOWN = 0x00008901
|
||||
SIOCSPGRP = 0x00008902
|
||||
FIOGETOWN = 0x00008903
|
||||
SIOCGPGRP = 0x00008904
|
||||
)
|
||||
|
||||
// ioctl(2) requests provided by uapi/linux/sockios.h
|
||||
const (
|
||||
SIOCGIFNAME = 0x8910
|
||||
SIOCGIFCONF = 0x8912
|
||||
SIOCGIFFLAGS = 0x8913
|
||||
SIOCGIFADDR = 0x8915
|
||||
SIOCGIFDSTADDR = 0x8917
|
||||
SIOCGIFBRDADDR = 0x8919
|
||||
SIOCGIFNETMASK = 0x891b
|
||||
SIOCGIFMETRIC = 0x891d
|
||||
SIOCGIFMTU = 0x8921
|
||||
SIOCGIFMEM = 0x891f
|
||||
SIOCGIFHWADDR = 0x8927
|
||||
SIOCGIFINDEX = 0x8933
|
||||
SIOCGIFPFLAGS = 0x8935
|
||||
SIOCGIFTXQLEN = 0x8942
|
||||
SIOCETHTOOL = 0x8946
|
||||
SIOCGMIIPHY = 0x8947
|
||||
SIOCGMIIREG = 0x8948
|
||||
SIOCGIFMAP = 0x8970
|
||||
)
|
||||
|
||||
// ioctl(2) requests provided by uapi/asm-generic/sockios.h
|
||||
const (
|
||||
SIOCGSTAMP = 0x8906
|
||||
)
|
||||
|
||||
// ioctl(2) directions. Used to calculate requests number.
|
||||
// Constants from asm-generic/ioctl.h.
|
||||
const (
|
||||
IOC_NONE = 0
|
||||
IOC_WRITE = 1
|
||||
IOC_READ = 2
|
||||
)
|
||||
|
||||
// Constants from asm-generic/ioctl.h.
|
||||
const (
|
||||
IOC_NRBITS = 8
|
||||
IOC_TYPEBITS = 8
|
||||
IOC_SIZEBITS = 14
|
||||
IOC_DIRBITS = 2
|
||||
|
||||
IOC_NRSHIFT = 0
|
||||
IOC_TYPESHIFT = IOC_NRSHIFT + IOC_NRBITS
|
||||
IOC_SIZESHIFT = IOC_TYPESHIFT + IOC_TYPEBITS
|
||||
IOC_DIRSHIFT = IOC_SIZESHIFT + IOC_SIZEBITS
|
||||
)
|
||||
|
||||
// IOC outputs the result of _IOC macro in include/uapi/asm-generic/ioctl.h.
|
||||
func IOC(dir, typ, nr, size uint32) uint32 {
|
||||
return uint32(dir)<<IOC_DIRSHIFT | typ<<IOC_TYPESHIFT | nr<<IOC_NRSHIFT | size<<IOC_SIZESHIFT
|
||||
}
|
||||
|
||||
// IO outputs the result of _IO macro in include/uapi/asm-generic/ioctl.h.
|
||||
func IO(typ, nr uint32) uint32 {
|
||||
return IOC(IOC_NONE, typ, nr, 0)
|
||||
}
|
||||
|
||||
// IOR outputs the result of _IOR macro in include/uapi/asm-generic/ioctl.h.
|
||||
func IOR(typ, nr, size uint32) uint32 {
|
||||
return IOC(IOC_READ, typ, nr, size)
|
||||
}
|
||||
|
||||
// IOW outputs the result of _IOW macro in include/uapi/asm-generic/ioctl.h.
|
||||
func IOW(typ, nr, size uint32) uint32 {
|
||||
return IOC(IOC_WRITE, typ, nr, size)
|
||||
}
|
||||
|
||||
// IOWR outputs the result of _IOWR macro in include/uapi/asm-generic/ioctl.h.
|
||||
func IOWR(typ, nr, size uint32) uint32 {
|
||||
return IOC(IOC_READ|IOC_WRITE, typ, nr, size)
|
||||
}
|
||||
|
||||
// IOC_NR outputs the result of IOC_NR macro in
|
||||
// include/uapi/asm-generic/ioctl.h.
|
||||
func IOC_NR(nr uint32) uint32 {
|
||||
return (nr >> IOC_NRSHIFT) & ((1 << IOC_NRBITS) - 1)
|
||||
}
|
||||
|
||||
// IOC_SIZE outputs the result of IOC_SIZE macro in
|
||||
// include/uapi/asm-generic/ioctl.h.
|
||||
func IOC_SIZE(nr uint32) uint32 {
|
||||
return (nr >> IOC_SIZESHIFT) & ((1 << IOC_SIZEBITS) - 1)
|
||||
}
|
||||
|
||||
/* Used for packet mode */
|
||||
const (
|
||||
TIOCPKT_DATA = 0
|
||||
TIOCPKT_FLUSHREAD = 1
|
||||
TIOCPKT_FLUSHWRITE = 2
|
||||
TIOCPKT_STOP = 4
|
||||
TIOCPKT_START = 8
|
||||
TIOCPKT_NOSTOP = 16
|
||||
TIOCPKT_DOSTOP = 32
|
||||
TIOCPKT_IOCTL = 64
|
||||
)
|
||||
|
||||
// Kcov ioctls from include/uapi/linux/kcov.h.
|
||||
var (
|
||||
KCOV_INIT_TRACE = IOR('c', 1, 8)
|
||||
KCOV_ENABLE = IO('c', 100)
|
||||
KCOV_DISABLE = IO('c', 101)
|
||||
)
|
||||
|
||||
// Kcov trace types from include/uapi/linux/kcov.h.
|
||||
const (
|
||||
KCOV_TRACE_PC = 0
|
||||
KCOV_TRACE_CMP = 1
|
||||
)
|
||||
|
||||
// Kcov state constants from include/uapi/linux/kcov.h.
|
||||
const (
|
||||
KCOV_MODE_DISABLED = 0
|
||||
KCOV_MODE_INIT = 1
|
||||
KCOV_MODE_TRACE_PC = 2
|
||||
KCOV_MODE_TRACE_CMP = 3
|
||||
)
|
||||
33
pkg/abi/linux/ioctl_tun.go
Normal file
33
pkg/abi/linux/ioctl_tun.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// ioctl(2) request numbers from linux/if_tun.h
|
||||
var (
|
||||
TUNSETIFF = IOW('T', 202, 4)
|
||||
TUNSETPERSIST = IOW('T', 203, 4)
|
||||
TUNGETIFF = IOR('T', 210, 4)
|
||||
)
|
||||
|
||||
// Flags from net/if_tun.h
|
||||
const (
|
||||
IFF_TUN = 0x0001
|
||||
IFF_TAP = 0x0002
|
||||
IFF_NO_PI = 0x1000
|
||||
IFF_NOFILTER = 0x1000
|
||||
IFF_TUN_EXCL = 0x8000
|
||||
// According to linux/if_tun.h "This flag has no real effect"
|
||||
IFF_ONE_QUEUE = 0x2000
|
||||
)
|
||||
238
pkg/abi/linux/iouring.go
Normal file
238
pkg/abi/linux/iouring.go
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
// Copyright 2022 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Constants for io_uring_setup(2). See include/uapi/linux/io_uring.h.
|
||||
const (
|
||||
IORING_SETUP_IOPOLL = (1 << 0)
|
||||
IORING_SETUP_SQPOLL = (1 << 1)
|
||||
IORING_SETUP_SQ_AFF = (1 << 2)
|
||||
IORING_SETUP_CQSIZE = (1 << 3)
|
||||
IORING_SETUP_CLAMP = (1 << 4)
|
||||
IORING_SETUP_ATTACH_WQ = (1 << 5)
|
||||
IORING_SETUP_R_DISABLED = (1 << 6)
|
||||
IORING_SETUP_SUBMIT_ALL = (1 << 7)
|
||||
)
|
||||
|
||||
// Constants for io_uring_enter(2). See include/uapi/linux/io_uring.h.
|
||||
const (
|
||||
IORING_ENTER_GETEVENTS = (1 << 0)
|
||||
)
|
||||
|
||||
// Constants for IoUringParams.Features. See include/uapi/linux/io_uring.h.
|
||||
const (
|
||||
IORING_FEAT_SINGLE_MMAP = (1 << 0)
|
||||
)
|
||||
|
||||
// Constants for IO_URING. See include/uapi/linux/io_uring.h.
|
||||
const (
|
||||
IORING_SETUP_COOP_TASKRUN = (1 << 8)
|
||||
IORING_SETUP_TASKRUN_FLAG = (1 << 9)
|
||||
IORING_SETUP_SQE128 = (1 << 10)
|
||||
IORING_SETUP_CQE32 = (1 << 11)
|
||||
)
|
||||
|
||||
// Constants for IO_URING. See io_uring/io_uring.c.
|
||||
const (
|
||||
IORING_MAX_ENTRIES = (1 << 15) // 32768
|
||||
IORING_MAX_CQ_ENTRIES = (2 * IORING_MAX_ENTRIES)
|
||||
)
|
||||
|
||||
// Constants for the offsets for the application to mmap the data it needs.
|
||||
// See include/uapi/linux/io_uring.h.
|
||||
const (
|
||||
IORING_OFF_SQ_RING = 0
|
||||
IORING_OFF_CQ_RING = 0x8000000
|
||||
IORING_OFF_SQES = 0x10000000
|
||||
)
|
||||
|
||||
// Constants for the IO_URING opcodes. See include/uapi/linux/io_uring.h.
|
||||
const (
|
||||
IORING_OP_NOP = 0
|
||||
IORING_OP_READV = 1
|
||||
)
|
||||
|
||||
// IORingIndex represents SQE array indexes.
|
||||
//
|
||||
// +marshal
|
||||
type IORingIndex uint32
|
||||
|
||||
// IOSqRingOffsets implements io_sqring_offsets struct.
|
||||
// IOSqRingOffsets represents offsets into IORings.
|
||||
// See struct io_sqring_offsets in include/uapi/linux/io_uring.h.
|
||||
//
|
||||
// +marshal
|
||||
type IOSqRingOffsets struct {
|
||||
Head uint32 // Offset to io_rings.sq.head
|
||||
Tail uint32 // Offset to io_rings.sq.tail
|
||||
RingMask uint32 // Offset to io_rings.sq_ring_mask
|
||||
RingEntries uint32 // Offset to io_rings.sq_ring_entries
|
||||
Flags uint32 // Offset to io_rings.sq_flags
|
||||
Dropped uint32 // Offset to io_rings.sq_dropped
|
||||
Array uint32 // Offset to an array of SQE indices
|
||||
Resv1 uint32 // Currently reserved and expected to be zero
|
||||
Resv2 uint64 // Currently reserved and expected to be zero
|
||||
}
|
||||
|
||||
// IOCqRingOffsets implements io_cqring_offsets struct.
|
||||
// IOCqRingOffsets represents offsets into IORings.
|
||||
// See struct io_cqring_offsets in include/uapi/linux/io_uring.h.
|
||||
//
|
||||
// +marshal
|
||||
type IOCqRingOffsets struct {
|
||||
Head uint32 // Offset to io_rings.cq.head
|
||||
Tail uint32 // Offset to io_rings.cq.tail
|
||||
RingMask uint32 // Offset to io_rings.cq_ring_mask
|
||||
RingEntries uint32 // Offset to io_rings.cq_ring_entries
|
||||
Overflow uint32 // Offset to io_rings.cq_overflow
|
||||
Cqes uint32 // Offset to io_rings.cqes
|
||||
Flags uint32 // Offset to io_rings.cq_flags
|
||||
Resv1 uint32 // Currently reserved and expected to be zero
|
||||
Resv2 uint64 // Currently reserved and expected to be zero
|
||||
}
|
||||
|
||||
// IOUringParams implements io_uring_params struct.
|
||||
// See struct io_uring_params in include/uapi/linux/io_uring.h.
|
||||
//
|
||||
// +marshal
|
||||
type IOUringParams struct {
|
||||
SqEntries uint32
|
||||
CqEntries uint32
|
||||
Flags uint32
|
||||
SqThreadCPU uint32
|
||||
SqThreadIdle uint32
|
||||
Features uint32
|
||||
WqFd uint32
|
||||
Resv [3]uint32
|
||||
SqOff IOSqRingOffsets
|
||||
CqOff IOCqRingOffsets
|
||||
}
|
||||
|
||||
// IOUringCqe implements IO completion data structure (Completion Queue Entry)
|
||||
// io_uring_cqe struct. As we don't currently support IORING_SETUP_CQE32 flag
|
||||
// its size is 16 bytes.
|
||||
// See struct io_uring_cqe in include/uapi/linux/io_uring.h.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type IOUringCqe struct {
|
||||
UserData uint64
|
||||
Res int32
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
// IOUring implements io_uring struct.
|
||||
// See struct io_uring in io_uring/io_uring.c.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type IOUring struct {
|
||||
// Both head and tail should be cacheline aligned. And we assume that
|
||||
// cacheline size is 64 bytes.
|
||||
Head uint32
|
||||
_ [60]byte
|
||||
Tail uint32
|
||||
_ [60]byte
|
||||
}
|
||||
|
||||
// IORings implements io_rings struct.
|
||||
// This struct describes layout of the mapped region backed by the ringBuffersFile.
|
||||
// See struct io_rings in io_uring/io_uring.c.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type IORings struct {
|
||||
Sq IOUring
|
||||
Cq IOUring
|
||||
SqRingMask uint32
|
||||
CqRingMask uint32
|
||||
SqRingEntries uint32
|
||||
CqRingEntries uint32
|
||||
sqDropped uint32
|
||||
sqFlags int32
|
||||
cqFlags uint32
|
||||
CqOverflow uint32
|
||||
_ [32]byte // Padding so cqes is cacheline aligned
|
||||
// Linux has an additional field struct io_uring_cqe cqes[], which represents
|
||||
// a dynamic array. We don't include it here in order to enable marshalling.
|
||||
}
|
||||
|
||||
// IOUringSqe implements io_uring_sqe struct.
|
||||
// This struct represents IO submission data structure (Submission Queue Entry). As we don't yet
|
||||
// support IORING_SETUP_SQE128 flag, its size is 64 bytes with no extra padding at the end.
|
||||
// See include/uapi/linux/io_uring.h.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type IOUringSqe struct {
|
||||
Opcode uint8
|
||||
Flags uint8
|
||||
IoPrio uint16
|
||||
Fd int32
|
||||
OffOrAddrOrCmdOp uint64
|
||||
AddrOrSpliceOff uint64
|
||||
Len uint32
|
||||
specialFlags uint32
|
||||
UserData uint64
|
||||
BufIndexOrGroup uint16
|
||||
personality uint16
|
||||
spliceFDOrFileIndex int32
|
||||
addr3 uint64
|
||||
_ uint64
|
||||
}
|
||||
|
||||
const (
|
||||
_IOSqRingOffset = 0 // +checkoffset . IORings.Sq
|
||||
_IOSqRingOffsetHead = 0 // +checkoffset . IOUring.Head
|
||||
_IOSqRingOffsetTail = 64 // +checkoffset . IOUring.Tail
|
||||
_IOSqRingOffsetMask = 256 // +checkoffset . IORings.SqRingMask
|
||||
_IOSqRingOffsetEntries = 264 // +checkoffset . IORings.SqRingEntries
|
||||
_IOSqRingOffsetFlags = 276 // +checkoffset . IORings.sqFlags
|
||||
_IOSqRingOffsetDropped = 272 // +checkoffset . IORings.sqDropped
|
||||
)
|
||||
|
||||
// PreComputedIOSqRingOffsets returns precomputed values for IOSqRingOffsets.
|
||||
func PreComputedIOSqRingOffsets() IOSqRingOffsets {
|
||||
return IOSqRingOffsets{
|
||||
Head: _IOSqRingOffset + _IOSqRingOffsetHead,
|
||||
Tail: _IOSqRingOffset + _IOSqRingOffsetTail,
|
||||
RingMask: _IOSqRingOffsetMask,
|
||||
RingEntries: _IOSqRingOffsetEntries,
|
||||
Flags: _IOSqRingOffsetFlags,
|
||||
Dropped: _IOSqRingOffsetDropped,
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
_IOCqRingOffset = 128 // +checkoffset . IORings.Cq
|
||||
_IOCqRingOffsetHead = 0 // +checkoffset . IOUring.Head
|
||||
_IOCqRingOffsetTail = 64 // +checkoffset . IOUring.Tail
|
||||
_IOCqRingOffsetMask = 260 // +checkoffset . IORings.CqRingMask
|
||||
_IOCqRingOffsetEntries = 268 // +checkoffset . IORings.CqRingEntries
|
||||
_IOCqRingOffsetFlags = 280 // +checkoffset . IORings.cqFlags
|
||||
_IOCqRingOffsetOverflow = 284 // +checkoffset . IORings.CqOverflow
|
||||
)
|
||||
|
||||
// PreComputedIOCqRingOffsets returns precomputed values for IOCqRingOffsets.
|
||||
func PreComputedIOCqRingOffsets() IOCqRingOffsets {
|
||||
return IOCqRingOffsets{
|
||||
Head: _IOCqRingOffset + _IOCqRingOffsetHead,
|
||||
Tail: _IOCqRingOffset + _IOCqRingOffsetTail,
|
||||
RingMask: _IOCqRingOffsetMask,
|
||||
RingEntries: _IOCqRingOffsetEntries,
|
||||
Overflow: _IOCqRingOffsetOverflow,
|
||||
Flags: _IOCqRingOffsetFlags,
|
||||
}
|
||||
}
|
||||
171
pkg/abi/linux/ip.go
Normal file
171
pkg/abi/linux/ip.go
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// IP protocols
|
||||
const (
|
||||
IPPROTO_IP = 0
|
||||
IPPROTO_ICMP = 1
|
||||
IPPROTO_IGMP = 2
|
||||
IPPROTO_IPIP = 4
|
||||
IPPROTO_TCP = 6
|
||||
IPPROTO_EGP = 8
|
||||
IPPROTO_PUP = 12
|
||||
IPPROTO_UDP = 17
|
||||
IPPROTO_IDP = 22
|
||||
IPPROTO_TP = 29
|
||||
IPPROTO_DCCP = 33
|
||||
IPPROTO_IPV6 = 41
|
||||
IPPROTO_RSVP = 46
|
||||
IPPROTO_GRE = 47
|
||||
IPPROTO_ESP = 50
|
||||
IPPROTO_AH = 51
|
||||
IPPROTO_ICMPV6 = 58
|
||||
IPPROTO_MTP = 92
|
||||
IPPROTO_BEETPH = 94
|
||||
IPPROTO_ENCAP = 98
|
||||
IPPROTO_PIM = 103
|
||||
IPPROTO_COMP = 108
|
||||
IPPROTO_SCTP = 132
|
||||
IPPROTO_UDPLITE = 136
|
||||
IPPROTO_MPLS = 137
|
||||
IPPROTO_RAW = 255
|
||||
)
|
||||
|
||||
// Socket options from uapi/linux/in.h
|
||||
const (
|
||||
IP_TOS = 1
|
||||
IP_TTL = 2
|
||||
IP_HDRINCL = 3
|
||||
IP_OPTIONS = 4
|
||||
IP_ROUTER_ALERT = 5
|
||||
IP_RECVOPTS = 6
|
||||
IP_RETOPTS = 7
|
||||
IP_PKTINFO = 8
|
||||
IP_PKTOPTIONS = 9
|
||||
IP_MTU_DISCOVER = 10
|
||||
IP_RECVERR = 11
|
||||
IP_RECVTTL = 12
|
||||
IP_RECVTOS = 13
|
||||
IP_MTU = 14
|
||||
IP_FREEBIND = 15
|
||||
IP_IPSEC_POLICY = 16
|
||||
IP_XFRM_POLICY = 17
|
||||
IP_PASSSEC = 18
|
||||
IP_TRANSPARENT = 19
|
||||
IP_ORIGDSTADDR = 20
|
||||
IP_RECVORIGDSTADDR = IP_ORIGDSTADDR
|
||||
IP_MINTTL = 21
|
||||
IP_NODEFRAG = 22
|
||||
IP_CHECKSUM = 23
|
||||
IP_BIND_ADDRESS_NO_PORT = 24
|
||||
IP_RECVFRAGSIZE = 25
|
||||
IP_RECVERR_RFC4884 = 26
|
||||
IP_MULTICAST_IF = 32
|
||||
IP_MULTICAST_TTL = 33
|
||||
IP_MULTICAST_LOOP = 34
|
||||
IP_ADD_MEMBERSHIP = 35
|
||||
IP_DROP_MEMBERSHIP = 36
|
||||
IP_UNBLOCK_SOURCE = 37
|
||||
IP_BLOCK_SOURCE = 38
|
||||
IP_ADD_SOURCE_MEMBERSHIP = 39
|
||||
IP_DROP_SOURCE_MEMBERSHIP = 40
|
||||
IP_MSFILTER = 41
|
||||
MCAST_JOIN_GROUP = 42
|
||||
MCAST_BLOCK_SOURCE = 43
|
||||
MCAST_UNBLOCK_SOURCE = 44
|
||||
MCAST_LEAVE_GROUP = 45
|
||||
MCAST_JOIN_SOURCE_GROUP = 46
|
||||
MCAST_LEAVE_SOURCE_GROUP = 47
|
||||
MCAST_MSFILTER = 48
|
||||
IP_MULTICAST_ALL = 49
|
||||
IP_UNICAST_IF = 50
|
||||
IP_LOCAL_PORT_RANGE = 51
|
||||
)
|
||||
|
||||
// IP_MTU_DISCOVER values from uapi/linux/in.h
|
||||
const (
|
||||
IP_PMTUDISC_DONT = 0
|
||||
IP_PMTUDISC_WANT = 1
|
||||
IP_PMTUDISC_DO = 2
|
||||
IP_PMTUDISC_PROBE = 3
|
||||
IP_PMTUDISC_INTERFACE = 4
|
||||
IP_PMTUDISC_OMIT = 5
|
||||
)
|
||||
|
||||
// Socket options from uapi/linux/in6.h
|
||||
const (
|
||||
IPV6_ADDRFORM = 1
|
||||
IPV6_2292PKTINFO = 2
|
||||
IPV6_2292HOPOPTS = 3
|
||||
IPV6_2292DSTOPTS = 4
|
||||
IPV6_2292RTHDR = 5
|
||||
IPV6_2292PKTOPTIONS = 6
|
||||
IPV6_CHECKSUM = 7
|
||||
IPV6_2292HOPLIMIT = 8
|
||||
IPV6_NEXTHOP = 9
|
||||
IPV6_FLOWINFO = 11
|
||||
IPV6_UNICAST_HOPS = 16
|
||||
IPV6_MULTICAST_IF = 17
|
||||
IPV6_MULTICAST_HOPS = 18
|
||||
IPV6_MULTICAST_LOOP = 19
|
||||
IPV6_ADD_MEMBERSHIP = 20
|
||||
IPV6_DROP_MEMBERSHIP = 21
|
||||
IPV6_ROUTER_ALERT = 22
|
||||
IPV6_MTU_DISCOVER = 23
|
||||
IPV6_MTU = 24
|
||||
IPV6_RECVERR = 25
|
||||
IPV6_V6ONLY = 26
|
||||
IPV6_JOIN_ANYCAST = 27
|
||||
IPV6_LEAVE_ANYCAST = 28
|
||||
IPV6_MULTICAST_ALL = 29
|
||||
IPV6_ROUTER_ALERT_ISOLATE = 30
|
||||
IPV6_RECVERR_RFC4884 = 31
|
||||
IPV6_FLOWLABEL_MGR = 32
|
||||
IPV6_FLOWINFO_SEND = 33
|
||||
IPV6_IPSEC_POLICY = 34
|
||||
IPV6_XFRM_POLICY = 35
|
||||
IPV6_HDRINCL = 36
|
||||
IPV6_RECVPKTINFO = 49
|
||||
IPV6_PKTINFO = 50
|
||||
IPV6_RECVHOPLIMIT = 51
|
||||
IPV6_HOPLIMIT = 52
|
||||
IPV6_RECVHOPOPTS = 53
|
||||
IPV6_HOPOPTS = 54
|
||||
IPV6_RTHDRDSTOPTS = 55
|
||||
IPV6_RECVRTHDR = 56
|
||||
IPV6_RTHDR = 57
|
||||
IPV6_RECVDSTOPTS = 58
|
||||
IPV6_DSTOPTS = 59
|
||||
IPV6_RECVPATHMTU = 60
|
||||
IPV6_PATHMTU = 61
|
||||
IPV6_DONTFRAG = 62
|
||||
IPV6_RECVTCLASS = 66
|
||||
IPV6_TCLASS = 67
|
||||
IPV6_AUTOFLOWLABEL = 70
|
||||
IPV6_ADDR_PREFERENCES = 72
|
||||
IPV6_MINHOPCOUNT = 73
|
||||
IPV6_ORIGDSTADDR = 74
|
||||
IPV6_RECVORIGDSTADDR = IPV6_ORIGDSTADDR
|
||||
IPV6_TRANSPARENT = 75
|
||||
IPV6_UNICAST_IF = 76
|
||||
IPV6_RECVFRAGSIZE = 77
|
||||
IPV6_FREEBIND = 78
|
||||
)
|
||||
|
||||
// Socket options from uapi/linux/icmpv6.h
|
||||
const (
|
||||
ICMPV6_FILTER = 1
|
||||
)
|
||||
61
pkg/abi/linux/ipc.go
Normal file
61
pkg/abi/linux/ipc.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Control commands used with semctl, shmctl, and msgctl.
|
||||
//
|
||||
// Source: include/uapi/linux/ipc.h.
|
||||
const (
|
||||
IPC_RMID = 0
|
||||
IPC_SET = 1
|
||||
IPC_STAT = 2
|
||||
IPC_INFO = 3
|
||||
)
|
||||
|
||||
// Resource get request flags.
|
||||
//
|
||||
// Source: include/uapi/linux/ipc.h
|
||||
const (
|
||||
IPC_CREAT = 0o0001000
|
||||
IPC_EXCL = 0o0002000
|
||||
IPC_NOWAIT = 0o0004000
|
||||
)
|
||||
|
||||
// IPC flags.
|
||||
const (
|
||||
IPC_PRIVATE = 0
|
||||
)
|
||||
|
||||
// In Linux, amd64 does not enable CONFIG_ARCH_WANT_IPC_PARSE_VERSION, so SysV
|
||||
// IPC unconditionally uses the "new" 64-bit structures that are needed for
|
||||
// features like 32-bit UIDs.
|
||||
|
||||
// IPCPerm is equivalent to struct ipc64_perm.
|
||||
//
|
||||
// +marshal
|
||||
type IPCPerm struct {
|
||||
Key uint32
|
||||
UID uint32
|
||||
GID uint32
|
||||
CUID uint32
|
||||
CGID uint32
|
||||
Mode uint16
|
||||
_ uint16
|
||||
Seq uint16
|
||||
_ uint16
|
||||
_ uint32
|
||||
unused1 uint64
|
||||
unused2 uint64
|
||||
}
|
||||
29
pkg/abi/linux/keyctl.go
Normal file
29
pkg/abi/linux/keyctl.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2023 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Constants used by keyctl(2) and other keyrings-related syscalls.
|
||||
// Source: include/uapi/linux/keyctl.h
|
||||
|
||||
const (
|
||||
KEY_SPEC_SESSION_KEYRING = -3
|
||||
)
|
||||
|
||||
const (
|
||||
KEYCTL_GET_KEYRING_ID = 0
|
||||
KEYCTL_JOIN_SESSION_KEYRING = 1
|
||||
KEYCTL_SETPERM = 5
|
||||
KEYCTL_DESCRIBE = 6
|
||||
)
|
||||
88
pkg/abi/linux/limits.go
Normal file
88
pkg/abi/linux/limits.go
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Resources for getrlimit(2)/setrlimit(2)/prlimit(2).
|
||||
const (
|
||||
RLIMIT_CPU = 0
|
||||
RLIMIT_FSIZE = 1
|
||||
RLIMIT_DATA = 2
|
||||
RLIMIT_STACK = 3
|
||||
RLIMIT_CORE = 4
|
||||
RLIMIT_RSS = 5
|
||||
RLIMIT_NPROC = 6
|
||||
RLIMIT_NOFILE = 7
|
||||
RLIMIT_MEMLOCK = 8
|
||||
RLIMIT_AS = 9
|
||||
RLIMIT_LOCKS = 10
|
||||
RLIMIT_SIGPENDING = 11
|
||||
RLIMIT_MSGQUEUE = 12
|
||||
RLIMIT_NICE = 13
|
||||
RLIMIT_RTPRIO = 14
|
||||
RLIMIT_RTTIME = 15
|
||||
)
|
||||
|
||||
// RLimit corresponds to Linux's struct rlimit.
|
||||
type RLimit struct {
|
||||
// Cur specifies the soft limit.
|
||||
Cur uint64
|
||||
// Max specifies the hard limit.
|
||||
Max uint64
|
||||
}
|
||||
|
||||
const (
|
||||
// RLimInfinity is RLIM_INFINITY on Linux.
|
||||
RLimInfinity = ^uint64(0)
|
||||
|
||||
// DefaultStackSoftLimit is called _STK_LIM in Linux.
|
||||
DefaultStackSoftLimit = 8 * 1024 * 1024
|
||||
|
||||
// DefaultNprocLimit is defined in kernel/fork.c:set_max_threads, and
|
||||
// called MAX_THREADS / 2 in Linux.
|
||||
DefaultNprocLimit = FUTEX_TID_MASK / 2
|
||||
|
||||
// DefaultNofileSoftLimit is called INR_OPEN_CUR in Linux.
|
||||
DefaultNofileSoftLimit = 1024
|
||||
|
||||
// DefaultNofileHardLimit is called INR_OPEN_MAX in Linux.
|
||||
DefaultNofileHardLimit = 4096
|
||||
|
||||
// DefaultMemlockLimit is called MLOCK_LIMIT in Linux.
|
||||
DefaultMemlockLimit = 64 * 1024
|
||||
|
||||
// DefaultMsgqueueLimit is called MQ_BYTES_MAX in Linux.
|
||||
DefaultMsgqueueLimit = 819200
|
||||
)
|
||||
|
||||
// InitRLimits is a map of initial rlimits set by Linux in
|
||||
// include/asm-generic/resource.h.
|
||||
var InitRLimits = map[int]RLimit{
|
||||
RLIMIT_CPU: {RLimInfinity, RLimInfinity},
|
||||
RLIMIT_FSIZE: {RLimInfinity, RLimInfinity},
|
||||
RLIMIT_DATA: {RLimInfinity, RLimInfinity},
|
||||
RLIMIT_STACK: {DefaultStackSoftLimit, RLimInfinity},
|
||||
RLIMIT_CORE: {0, RLimInfinity},
|
||||
RLIMIT_RSS: {RLimInfinity, RLimInfinity},
|
||||
RLIMIT_NPROC: {DefaultNprocLimit, DefaultNprocLimit},
|
||||
RLIMIT_NOFILE: {DefaultNofileSoftLimit, DefaultNofileHardLimit},
|
||||
RLIMIT_MEMLOCK: {DefaultMemlockLimit, DefaultMemlockLimit},
|
||||
RLIMIT_AS: {RLimInfinity, RLimInfinity},
|
||||
RLIMIT_LOCKS: {RLimInfinity, RLimInfinity},
|
||||
RLIMIT_SIGPENDING: {0, 0},
|
||||
RLIMIT_MSGQUEUE: {DefaultMsgqueueLimit, DefaultMsgqueueLimit},
|
||||
RLIMIT_NICE: {0, 0},
|
||||
RLIMIT_RTPRIO: {0, 0},
|
||||
RLIMIT_RTTIME: {RLimInfinity, RLimInfinity},
|
||||
}
|
||||
42
pkg/abi/linux/linux.go
Normal file
42
pkg/abi/linux/linux.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package linux contains the constants and types needed to interface with a
|
||||
// Linux kernel.
|
||||
package linux
|
||||
|
||||
// NumSoftIRQ is the number of software IRQs, exposed via /proc/stat.
|
||||
//
|
||||
// Defined in linux/interrupt.h.
|
||||
const NumSoftIRQ = 10
|
||||
|
||||
// Sysinfo is the structure provided by sysinfo on linux versions > 2.3.48.
|
||||
//
|
||||
// +marshal
|
||||
type Sysinfo struct {
|
||||
Uptime int64
|
||||
Loads [3]uint64
|
||||
TotalRAM uint64
|
||||
FreeRAM uint64
|
||||
SharedRAM uint64
|
||||
BufferRAM uint64
|
||||
TotalSwap uint64
|
||||
FreeSwap uint64
|
||||
Procs uint16
|
||||
_ [6]byte // Pad Procs to 64bits.
|
||||
TotalHigh uint64
|
||||
FreeHigh uint64
|
||||
Unit uint32 `marshal:"unaligned"` // Struct ends mid-64-bit-word.
|
||||
// The _f field in the glibc version of Sysinfo has size 0 on AMD64.
|
||||
}
|
||||
22507
pkg/abi/linux/linux_abi_autogen_unsafe.go
Normal file
22507
pkg/abi/linux/linux_abi_autogen_unsafe.go
Normal file
File diff suppressed because it is too large
Load diff
760
pkg/abi/linux/linux_amd64_abi_autogen_unsafe.go
Normal file
760
pkg/abi/linux/linux_amd64_abi_autogen_unsafe.go
Normal file
|
|
@ -0,0 +1,760 @@
|
|||
// Automatically generated marshal implementation. See tools/go_marshal.
|
||||
|
||||
// If there are issues with build constraint aggregation, see
|
||||
// tools/go_marshal/gomarshal/generator.go:writeHeader(). The constraints here
|
||||
// come from the input set of files used to generate this file. This input set
|
||||
// is filtered based on pre-defined file suffixes related to build constraints,
|
||||
// see tools/defs.bzl:calculate_sets().
|
||||
|
||||
//go:build amd64 && amd64 && amd64 && amd64 && amd64 && amd64
|
||||
// +build amd64,amd64,amd64,amd64,amd64,amd64
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"io"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/gohacks"
|
||||
"github.com/sagernet/gvisor/pkg/hostarch"
|
||||
"github.com/sagernet/gvisor/pkg/marshal"
|
||||
)
|
||||
|
||||
// Marshallable types used by this file.
|
||||
var (
|
||||
_ marshal.Marshallable = (*EpollEvent)(nil)
|
||||
_ marshal.Marshallable = (*IPCPerm)(nil)
|
||||
_ marshal.Marshallable = (*PtraceRegs)(nil)
|
||||
_ marshal.Marshallable = (*SemidDS)(nil)
|
||||
_ marshal.Marshallable = (*Stat)(nil)
|
||||
_ marshal.Marshallable = (*TimeT)(nil)
|
||||
_ marshal.Marshallable = (*Timespec)(nil)
|
||||
)
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (e *EpollEvent) SizeBytes() int {
|
||||
return 4 +
|
||||
4*2
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (e *EpollEvent) MarshalBytes(dst []byte) []byte {
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Events))
|
||||
dst = dst[4:]
|
||||
for idx := 0; idx < 2; idx++ {
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Data[idx]))
|
||||
dst = dst[4:]
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (e *EpollEvent) UnmarshalBytes(src []byte) []byte {
|
||||
e.Events = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
for idx := 0; idx < 2; idx++ {
|
||||
e.Data[idx] = int32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
}
|
||||
return src
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
//
|
||||
//go:nosplit
|
||||
func (e *EpollEvent) Packed() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (e *EpollEvent) MarshalUnsafe(dst []byte) []byte {
|
||||
size := e.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(e), uintptr(size))
|
||||
return dst[size:]
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (e *EpollEvent) UnmarshalUnsafe(src []byte) []byte {
|
||||
size := e.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(e), unsafe.Pointer(&src[0]), uintptr(size))
|
||||
return src[size:]
|
||||
}
|
||||
|
||||
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||
func (e *EpollEvent) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||
hdr.Len = e.SizeBytes()
|
||||
hdr.Cap = e.SizeBytes()
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||
func (e *EpollEvent) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return e.CopyOutN(cc, addr, e.SizeBytes())
|
||||
}
|
||||
|
||||
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||
func (e *EpollEvent) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||
hdr.Len = e.SizeBytes()
|
||||
hdr.Cap = e.SizeBytes()
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
func (e *EpollEvent) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return e.CopyInN(cc, addr, e.SizeBytes())
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.WriteTo.
|
||||
func (e *EpollEvent) WriteTo(writer io.Writer) (int64, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||
hdr.Len = e.SizeBytes()
|
||||
hdr.Cap = e.SizeBytes()
|
||||
|
||||
length, err := writer.Write(buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// CopyEpollEventSliceIn copies in a slice of EpollEvent objects from the task's memory.
|
||||
func CopyEpollEventSliceIn(cc marshal.CopyContext, addr hostarch.Addr, dst []EpollEvent) (int, error) {
|
||||
count := len(dst)
|
||||
if count == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
size := (*EpollEvent)(nil).SizeBytes()
|
||||
|
||||
ptr := unsafe.Pointer(&dst)
|
||||
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(val)
|
||||
hdr.Len = size * count
|
||||
hdr.Cap = size * count
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that dst
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(dst) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyEpollEventSliceOut copies a slice of EpollEvent objects to the task's memory.
|
||||
func CopyEpollEventSliceOut(cc marshal.CopyContext, addr hostarch.Addr, src []EpollEvent) (int, error) {
|
||||
count := len(src)
|
||||
if count == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
size := (*EpollEvent)(nil).SizeBytes()
|
||||
|
||||
ptr := unsafe.Pointer(&src)
|
||||
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(val)
|
||||
hdr.Len = size * count
|
||||
hdr.Cap = size * count
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that src
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(src) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// MarshalUnsafeEpollEventSlice is like EpollEvent.MarshalUnsafe, but for a []EpollEvent.
|
||||
func MarshalUnsafeEpollEventSlice(src []EpollEvent, dst []byte) []byte {
|
||||
count := len(src)
|
||||
if count == 0 {
|
||||
return dst
|
||||
}
|
||||
|
||||
size := (*EpollEvent)(nil).SizeBytes()
|
||||
buf := dst[:size*count]
|
||||
gohacks.Memmove(unsafe.Pointer(&buf[0]), unsafe.Pointer(&src[0]), uintptr(len(buf)))
|
||||
return dst[size*count:]
|
||||
}
|
||||
|
||||
// UnmarshalUnsafeEpollEventSlice is like EpollEvent.UnmarshalUnsafe, but for a []EpollEvent.
|
||||
func UnmarshalUnsafeEpollEventSlice(dst []EpollEvent, src []byte) []byte {
|
||||
count := len(dst)
|
||||
if count == 0 {
|
||||
return src
|
||||
}
|
||||
|
||||
size := (*EpollEvent)(nil).SizeBytes()
|
||||
buf := src[:size*count]
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&buf[0]), uintptr(len(buf)))
|
||||
return src[size*count:]
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (s *Stat) SizeBytes() int {
|
||||
return 72 +
|
||||
(*Timespec)(nil).SizeBytes() +
|
||||
(*Timespec)(nil).SizeBytes() +
|
||||
(*Timespec)(nil).SizeBytes() +
|
||||
8*3
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (s *Stat) MarshalBytes(dst []byte) []byte {
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Dev))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Ino))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Nlink))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Mode))
|
||||
dst = dst[4:]
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.UID))
|
||||
dst = dst[4:]
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.GID))
|
||||
dst = dst[4:]
|
||||
// Padding: dst[:sizeof(int32)] ~= int32(0)
|
||||
dst = dst[4:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Rdev))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Size))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Blksize))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Blocks))
|
||||
dst = dst[8:]
|
||||
dst = s.ATime.MarshalUnsafe(dst)
|
||||
dst = s.MTime.MarshalUnsafe(dst)
|
||||
dst = s.CTime.MarshalUnsafe(dst)
|
||||
// Padding: dst[:sizeof(int64)*3] ~= [3]int64{0}
|
||||
dst = dst[8*(3):]
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (s *Stat) UnmarshalBytes(src []byte) []byte {
|
||||
s.Dev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.Ino = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.Nlink = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.Mode = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
s.UID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
s.GID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
// Padding: var _ int32 ~= src[:sizeof(int32)]
|
||||
src = src[4:]
|
||||
s.Rdev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.Size = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.Blksize = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.Blocks = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
src = s.ATime.UnmarshalUnsafe(src)
|
||||
src = s.MTime.UnmarshalUnsafe(src)
|
||||
src = s.CTime.UnmarshalUnsafe(src)
|
||||
// Padding: ~ copy([3]int64(s._), src[:sizeof(int64)*3])
|
||||
src = src[8*(3):]
|
||||
return src
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
//
|
||||
//go:nosplit
|
||||
func (s *Stat) Packed() bool {
|
||||
return s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed()
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (s *Stat) MarshalUnsafe(dst []byte) []byte {
|
||||
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
size := s.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
|
||||
return dst[size:]
|
||||
}
|
||||
// Type Stat doesn't have a packed layout in memory, fallback to MarshalBytes.
|
||||
return s.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (s *Stat) UnmarshalUnsafe(src []byte) []byte {
|
||||
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
size := s.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
|
||||
return src[size:]
|
||||
}
|
||||
// Type Stat doesn't have a packed layout in memory, fallback to UnmarshalBytes.
|
||||
return s.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||
func (s *Stat) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||
s.MarshalBytes(buf) // escapes: fallback.
|
||||
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||
func (s *Stat) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return s.CopyOutN(cc, addr, s.SizeBytes())
|
||||
}
|
||||
|
||||
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||
func (s *Stat) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
// Type Stat doesn't have a packed layout in memory, fall back to UnmarshalBytes.
|
||||
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Unmarshal unconditionally. If we had a short copy-in, this results in a
|
||||
// partially unmarshalled struct.
|
||||
s.UnmarshalBytes(buf) // escapes: fallback.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
func (s *Stat) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return s.CopyInN(cc, addr, s.SizeBytes())
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.WriteTo.
|
||||
func (s *Stat) WriteTo(writer io.Writer) (int64, error) {
|
||||
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||
buf := make([]byte, s.SizeBytes())
|
||||
s.MarshalBytes(buf)
|
||||
length, err := writer.Write(buf)
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := writer.Write(buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (p *PtraceRegs) SizeBytes() int {
|
||||
return 216
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (p *PtraceRegs) MarshalBytes(dst []byte) []byte {
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R15))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R14))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R13))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R12))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rbp))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rbx))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R11))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R10))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R9))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R8))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rax))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rcx))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rdx))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rsi))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rdi))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Orig_rax))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rip))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Cs))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Eflags))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rsp))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Ss))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Fs_base))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Gs_base))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Ds))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Es))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Fs))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Gs))
|
||||
dst = dst[8:]
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (p *PtraceRegs) UnmarshalBytes(src []byte) []byte {
|
||||
p.R15 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.R14 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.R13 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.R12 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Rbp = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Rbx = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.R11 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.R10 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.R9 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.R8 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Rax = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Rcx = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Rdx = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Rsi = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Rdi = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Orig_rax = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Rip = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Cs = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Eflags = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Rsp = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Ss = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Fs_base = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Gs_base = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Ds = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Es = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Fs = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Gs = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
return src
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
//
|
||||
//go:nosplit
|
||||
func (p *PtraceRegs) Packed() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (p *PtraceRegs) MarshalUnsafe(dst []byte) []byte {
|
||||
size := p.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(p), uintptr(size))
|
||||
return dst[size:]
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (p *PtraceRegs) UnmarshalUnsafe(src []byte) []byte {
|
||||
size := p.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(p), unsafe.Pointer(&src[0]), uintptr(size))
|
||||
return src[size:]
|
||||
}
|
||||
|
||||
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||
func (p *PtraceRegs) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||
hdr.Len = p.SizeBytes()
|
||||
hdr.Cap = p.SizeBytes()
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||
func (p *PtraceRegs) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return p.CopyOutN(cc, addr, p.SizeBytes())
|
||||
}
|
||||
|
||||
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||
func (p *PtraceRegs) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||
hdr.Len = p.SizeBytes()
|
||||
hdr.Cap = p.SizeBytes()
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
func (p *PtraceRegs) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return p.CopyInN(cc, addr, p.SizeBytes())
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.WriteTo.
|
||||
func (p *PtraceRegs) WriteTo(writer io.Writer) (int64, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||
hdr.Len = p.SizeBytes()
|
||||
hdr.Cap = p.SizeBytes()
|
||||
|
||||
length, err := writer.Write(buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (s *SemidDS) SizeBytes() int {
|
||||
return 40 +
|
||||
(*IPCPerm)(nil).SizeBytes() +
|
||||
(*TimeT)(nil).SizeBytes() +
|
||||
(*TimeT)(nil).SizeBytes()
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (s *SemidDS) MarshalBytes(dst []byte) []byte {
|
||||
dst = s.SemPerm.MarshalUnsafe(dst)
|
||||
dst = s.SemOTime.MarshalUnsafe(dst)
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused1))
|
||||
dst = dst[8:]
|
||||
dst = s.SemCTime.MarshalUnsafe(dst)
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused2))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.SemNSems))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused3))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused4))
|
||||
dst = dst[8:]
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (s *SemidDS) UnmarshalBytes(src []byte) []byte {
|
||||
src = s.SemPerm.UnmarshalUnsafe(src)
|
||||
src = s.SemOTime.UnmarshalUnsafe(src)
|
||||
s.unused1 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
src = s.SemCTime.UnmarshalUnsafe(src)
|
||||
s.unused2 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.SemNSems = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.unused3 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.unused4 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
return src
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
//
|
||||
//go:nosplit
|
||||
func (s *SemidDS) Packed() bool {
|
||||
return s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed()
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (s *SemidDS) MarshalUnsafe(dst []byte) []byte {
|
||||
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
size := s.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
|
||||
return dst[size:]
|
||||
}
|
||||
// Type SemidDS doesn't have a packed layout in memory, fallback to MarshalBytes.
|
||||
return s.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (s *SemidDS) UnmarshalUnsafe(src []byte) []byte {
|
||||
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
size := s.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
|
||||
return src[size:]
|
||||
}
|
||||
// Type SemidDS doesn't have a packed layout in memory, fallback to UnmarshalBytes.
|
||||
return s.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||
func (s *SemidDS) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||
s.MarshalBytes(buf) // escapes: fallback.
|
||||
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||
func (s *SemidDS) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return s.CopyOutN(cc, addr, s.SizeBytes())
|
||||
}
|
||||
|
||||
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||
func (s *SemidDS) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
// Type SemidDS doesn't have a packed layout in memory, fall back to UnmarshalBytes.
|
||||
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Unmarshal unconditionally. If we had a short copy-in, this results in a
|
||||
// partially unmarshalled struct.
|
||||
s.UnmarshalBytes(buf) // escapes: fallback.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
func (s *SemidDS) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return s.CopyInN(cc, addr, s.SizeBytes())
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.WriteTo.
|
||||
func (s *SemidDS) WriteTo(writer io.Writer) (int64, error) {
|
||||
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||
buf := make([]byte, s.SizeBytes())
|
||||
s.MarshalBytes(buf)
|
||||
length, err := writer.Write(buf)
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := writer.Write(buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return int64(length), err
|
||||
}
|
||||
119
pkg/abi/linux/linux_amd64_state_autogen.go
Normal file
119
pkg/abi/linux/linux_amd64_state_autogen.go
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
// automatically generated by stateify.
|
||||
|
||||
//go:build amd64 && amd64 && amd64 && amd64 && amd64 && amd64
|
||||
// +build amd64,amd64,amd64,amd64,amd64,amd64
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/state"
|
||||
)
|
||||
|
||||
func (p *PtraceRegs) StateTypeName() string {
|
||||
return "pkg/abi/linux.PtraceRegs"
|
||||
}
|
||||
|
||||
func (p *PtraceRegs) StateFields() []string {
|
||||
return []string{
|
||||
"R15",
|
||||
"R14",
|
||||
"R13",
|
||||
"R12",
|
||||
"Rbp",
|
||||
"Rbx",
|
||||
"R11",
|
||||
"R10",
|
||||
"R9",
|
||||
"R8",
|
||||
"Rax",
|
||||
"Rcx",
|
||||
"Rdx",
|
||||
"Rsi",
|
||||
"Rdi",
|
||||
"Orig_rax",
|
||||
"Rip",
|
||||
"Cs",
|
||||
"Eflags",
|
||||
"Rsp",
|
||||
"Ss",
|
||||
"Fs_base",
|
||||
"Gs_base",
|
||||
"Ds",
|
||||
"Es",
|
||||
"Fs",
|
||||
"Gs",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PtraceRegs) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (p *PtraceRegs) StateSave(stateSinkObject state.Sink) {
|
||||
p.beforeSave()
|
||||
stateSinkObject.Save(0, &p.R15)
|
||||
stateSinkObject.Save(1, &p.R14)
|
||||
stateSinkObject.Save(2, &p.R13)
|
||||
stateSinkObject.Save(3, &p.R12)
|
||||
stateSinkObject.Save(4, &p.Rbp)
|
||||
stateSinkObject.Save(5, &p.Rbx)
|
||||
stateSinkObject.Save(6, &p.R11)
|
||||
stateSinkObject.Save(7, &p.R10)
|
||||
stateSinkObject.Save(8, &p.R9)
|
||||
stateSinkObject.Save(9, &p.R8)
|
||||
stateSinkObject.Save(10, &p.Rax)
|
||||
stateSinkObject.Save(11, &p.Rcx)
|
||||
stateSinkObject.Save(12, &p.Rdx)
|
||||
stateSinkObject.Save(13, &p.Rsi)
|
||||
stateSinkObject.Save(14, &p.Rdi)
|
||||
stateSinkObject.Save(15, &p.Orig_rax)
|
||||
stateSinkObject.Save(16, &p.Rip)
|
||||
stateSinkObject.Save(17, &p.Cs)
|
||||
stateSinkObject.Save(18, &p.Eflags)
|
||||
stateSinkObject.Save(19, &p.Rsp)
|
||||
stateSinkObject.Save(20, &p.Ss)
|
||||
stateSinkObject.Save(21, &p.Fs_base)
|
||||
stateSinkObject.Save(22, &p.Gs_base)
|
||||
stateSinkObject.Save(23, &p.Ds)
|
||||
stateSinkObject.Save(24, &p.Es)
|
||||
stateSinkObject.Save(25, &p.Fs)
|
||||
stateSinkObject.Save(26, &p.Gs)
|
||||
}
|
||||
|
||||
func (p *PtraceRegs) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (p *PtraceRegs) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &p.R15)
|
||||
stateSourceObject.Load(1, &p.R14)
|
||||
stateSourceObject.Load(2, &p.R13)
|
||||
stateSourceObject.Load(3, &p.R12)
|
||||
stateSourceObject.Load(4, &p.Rbp)
|
||||
stateSourceObject.Load(5, &p.Rbx)
|
||||
stateSourceObject.Load(6, &p.R11)
|
||||
stateSourceObject.Load(7, &p.R10)
|
||||
stateSourceObject.Load(8, &p.R9)
|
||||
stateSourceObject.Load(9, &p.R8)
|
||||
stateSourceObject.Load(10, &p.Rax)
|
||||
stateSourceObject.Load(11, &p.Rcx)
|
||||
stateSourceObject.Load(12, &p.Rdx)
|
||||
stateSourceObject.Load(13, &p.Rsi)
|
||||
stateSourceObject.Load(14, &p.Rdi)
|
||||
stateSourceObject.Load(15, &p.Orig_rax)
|
||||
stateSourceObject.Load(16, &p.Rip)
|
||||
stateSourceObject.Load(17, &p.Cs)
|
||||
stateSourceObject.Load(18, &p.Eflags)
|
||||
stateSourceObject.Load(19, &p.Rsp)
|
||||
stateSourceObject.Load(20, &p.Ss)
|
||||
stateSourceObject.Load(21, &p.Fs_base)
|
||||
stateSourceObject.Load(22, &p.Gs_base)
|
||||
stateSourceObject.Load(23, &p.Ds)
|
||||
stateSourceObject.Load(24, &p.Es)
|
||||
stateSourceObject.Load(25, &p.Fs)
|
||||
stateSourceObject.Load(26, &p.Gs)
|
||||
}
|
||||
|
||||
func init() {
|
||||
state.Register((*PtraceRegs)(nil))
|
||||
}
|
||||
673
pkg/abi/linux/linux_arm64_abi_autogen_unsafe.go
Normal file
673
pkg/abi/linux/linux_arm64_abi_autogen_unsafe.go
Normal file
|
|
@ -0,0 +1,673 @@
|
|||
// Automatically generated marshal implementation. See tools/go_marshal.
|
||||
|
||||
// If there are issues with build constraint aggregation, see
|
||||
// tools/go_marshal/gomarshal/generator.go:writeHeader(). The constraints here
|
||||
// come from the input set of files used to generate this file. This input set
|
||||
// is filtered based on pre-defined file suffixes related to build constraints,
|
||||
// see tools/defs.bzl:calculate_sets().
|
||||
|
||||
//go:build arm64 && arm64 && arm64 && arm64 && arm64
|
||||
// +build arm64,arm64,arm64,arm64,arm64
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"io"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/gohacks"
|
||||
"github.com/sagernet/gvisor/pkg/hostarch"
|
||||
"github.com/sagernet/gvisor/pkg/marshal"
|
||||
)
|
||||
|
||||
// Marshallable types used by this file.
|
||||
var (
|
||||
_ marshal.Marshallable = (*EpollEvent)(nil)
|
||||
_ marshal.Marshallable = (*IPCPerm)(nil)
|
||||
_ marshal.Marshallable = (*PtraceRegs)(nil)
|
||||
_ marshal.Marshallable = (*SemidDS)(nil)
|
||||
_ marshal.Marshallable = (*Stat)(nil)
|
||||
_ marshal.Marshallable = (*TimeT)(nil)
|
||||
_ marshal.Marshallable = (*Timespec)(nil)
|
||||
)
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (e *EpollEvent) SizeBytes() int {
|
||||
return 8 +
|
||||
4*2
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (e *EpollEvent) MarshalBytes(dst []byte) []byte {
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Events))
|
||||
dst = dst[4:]
|
||||
// Padding: dst[:sizeof(int32)] ~= int32(0)
|
||||
dst = dst[4:]
|
||||
for idx := 0; idx < 2; idx++ {
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Data[idx]))
|
||||
dst = dst[4:]
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (e *EpollEvent) UnmarshalBytes(src []byte) []byte {
|
||||
e.Events = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
// Padding: var _ int32 ~= src[:sizeof(int32)]
|
||||
src = src[4:]
|
||||
for idx := 0; idx < 2; idx++ {
|
||||
e.Data[idx] = int32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
}
|
||||
return src
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
//
|
||||
//go:nosplit
|
||||
func (e *EpollEvent) Packed() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (e *EpollEvent) MarshalUnsafe(dst []byte) []byte {
|
||||
size := e.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(e), uintptr(size))
|
||||
return dst[size:]
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (e *EpollEvent) UnmarshalUnsafe(src []byte) []byte {
|
||||
size := e.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(e), unsafe.Pointer(&src[0]), uintptr(size))
|
||||
return src[size:]
|
||||
}
|
||||
|
||||
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||
func (e *EpollEvent) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||
hdr.Len = e.SizeBytes()
|
||||
hdr.Cap = e.SizeBytes()
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||
func (e *EpollEvent) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return e.CopyOutN(cc, addr, e.SizeBytes())
|
||||
}
|
||||
|
||||
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||
func (e *EpollEvent) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||
hdr.Len = e.SizeBytes()
|
||||
hdr.Cap = e.SizeBytes()
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
func (e *EpollEvent) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return e.CopyInN(cc, addr, e.SizeBytes())
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.WriteTo.
|
||||
func (e *EpollEvent) WriteTo(writer io.Writer) (int64, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||
hdr.Len = e.SizeBytes()
|
||||
hdr.Cap = e.SizeBytes()
|
||||
|
||||
length, err := writer.Write(buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// CopyEpollEventSliceIn copies in a slice of EpollEvent objects from the task's memory.
|
||||
func CopyEpollEventSliceIn(cc marshal.CopyContext, addr hostarch.Addr, dst []EpollEvent) (int, error) {
|
||||
count := len(dst)
|
||||
if count == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
size := (*EpollEvent)(nil).SizeBytes()
|
||||
|
||||
ptr := unsafe.Pointer(&dst)
|
||||
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(val)
|
||||
hdr.Len = size * count
|
||||
hdr.Cap = size * count
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that dst
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(dst) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyEpollEventSliceOut copies a slice of EpollEvent objects to the task's memory.
|
||||
func CopyEpollEventSliceOut(cc marshal.CopyContext, addr hostarch.Addr, src []EpollEvent) (int, error) {
|
||||
count := len(src)
|
||||
if count == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
size := (*EpollEvent)(nil).SizeBytes()
|
||||
|
||||
ptr := unsafe.Pointer(&src)
|
||||
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(val)
|
||||
hdr.Len = size * count
|
||||
hdr.Cap = size * count
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that src
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(src) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// MarshalUnsafeEpollEventSlice is like EpollEvent.MarshalUnsafe, but for a []EpollEvent.
|
||||
func MarshalUnsafeEpollEventSlice(src []EpollEvent, dst []byte) []byte {
|
||||
count := len(src)
|
||||
if count == 0 {
|
||||
return dst
|
||||
}
|
||||
|
||||
size := (*EpollEvent)(nil).SizeBytes()
|
||||
buf := dst[:size*count]
|
||||
gohacks.Memmove(unsafe.Pointer(&buf[0]), unsafe.Pointer(&src[0]), uintptr(len(buf)))
|
||||
return dst[size*count:]
|
||||
}
|
||||
|
||||
// UnmarshalUnsafeEpollEventSlice is like EpollEvent.UnmarshalUnsafe, but for a []EpollEvent.
|
||||
func UnmarshalUnsafeEpollEventSlice(dst []EpollEvent, src []byte) []byte {
|
||||
count := len(dst)
|
||||
if count == 0 {
|
||||
return src
|
||||
}
|
||||
|
||||
size := (*EpollEvent)(nil).SizeBytes()
|
||||
buf := src[:size*count]
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&buf[0]), uintptr(len(buf)))
|
||||
return src[size*count:]
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (s *Stat) SizeBytes() int {
|
||||
return 72 +
|
||||
(*Timespec)(nil).SizeBytes() +
|
||||
(*Timespec)(nil).SizeBytes() +
|
||||
(*Timespec)(nil).SizeBytes() +
|
||||
4*2
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (s *Stat) MarshalBytes(dst []byte) []byte {
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Dev))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Ino))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Mode))
|
||||
dst = dst[4:]
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Nlink))
|
||||
dst = dst[4:]
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.UID))
|
||||
dst = dst[4:]
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.GID))
|
||||
dst = dst[4:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Rdev))
|
||||
dst = dst[8:]
|
||||
// Padding: dst[:sizeof(uint64)] ~= uint64(0)
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Size))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Blksize))
|
||||
dst = dst[4:]
|
||||
// Padding: dst[:sizeof(int32)] ~= int32(0)
|
||||
dst = dst[4:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Blocks))
|
||||
dst = dst[8:]
|
||||
dst = s.ATime.MarshalUnsafe(dst)
|
||||
dst = s.MTime.MarshalUnsafe(dst)
|
||||
dst = s.CTime.MarshalUnsafe(dst)
|
||||
// Padding: dst[:sizeof(int32)*2] ~= [2]int32{0}
|
||||
dst = dst[4*(2):]
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (s *Stat) UnmarshalBytes(src []byte) []byte {
|
||||
s.Dev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.Ino = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.Mode = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
s.Nlink = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
s.UID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
s.GID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
s.Rdev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
// Padding: var _ uint64 ~= src[:sizeof(uint64)]
|
||||
src = src[8:]
|
||||
s.Size = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.Blksize = int32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||
src = src[4:]
|
||||
// Padding: var _ int32 ~= src[:sizeof(int32)]
|
||||
src = src[4:]
|
||||
s.Blocks = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
src = s.ATime.UnmarshalUnsafe(src)
|
||||
src = s.MTime.UnmarshalUnsafe(src)
|
||||
src = s.CTime.UnmarshalUnsafe(src)
|
||||
// Padding: ~ copy([2]int32(s._), src[:sizeof(int32)*2])
|
||||
src = src[4*(2):]
|
||||
return src
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
//
|
||||
//go:nosplit
|
||||
func (s *Stat) Packed() bool {
|
||||
return s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed()
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (s *Stat) MarshalUnsafe(dst []byte) []byte {
|
||||
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
size := s.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
|
||||
return dst[size:]
|
||||
}
|
||||
// Type Stat doesn't have a packed layout in memory, fallback to MarshalBytes.
|
||||
return s.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (s *Stat) UnmarshalUnsafe(src []byte) []byte {
|
||||
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
size := s.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
|
||||
return src[size:]
|
||||
}
|
||||
// Type Stat doesn't have a packed layout in memory, fallback to UnmarshalBytes.
|
||||
return s.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||
func (s *Stat) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||
s.MarshalBytes(buf) // escapes: fallback.
|
||||
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||
func (s *Stat) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return s.CopyOutN(cc, addr, s.SizeBytes())
|
||||
}
|
||||
|
||||
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||
func (s *Stat) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
// Type Stat doesn't have a packed layout in memory, fall back to UnmarshalBytes.
|
||||
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Unmarshal unconditionally. If we had a short copy-in, this results in a
|
||||
// partially unmarshalled struct.
|
||||
s.UnmarshalBytes(buf) // escapes: fallback.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
func (s *Stat) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return s.CopyInN(cc, addr, s.SizeBytes())
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.WriteTo.
|
||||
func (s *Stat) WriteTo(writer io.Writer) (int64, error) {
|
||||
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||
buf := make([]byte, s.SizeBytes())
|
||||
s.MarshalBytes(buf)
|
||||
length, err := writer.Write(buf)
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := writer.Write(buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (p *PtraceRegs) SizeBytes() int {
|
||||
return 24 +
|
||||
8*31
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (p *PtraceRegs) MarshalBytes(dst []byte) []byte {
|
||||
for idx := 0; idx < 31; idx++ {
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Regs[idx]))
|
||||
dst = dst[8:]
|
||||
}
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Sp))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Pc))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Pstate))
|
||||
dst = dst[8:]
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (p *PtraceRegs) UnmarshalBytes(src []byte) []byte {
|
||||
for idx := 0; idx < 31; idx++ {
|
||||
p.Regs[idx] = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
}
|
||||
p.Sp = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Pc = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
p.Pstate = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
return src
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
//
|
||||
//go:nosplit
|
||||
func (p *PtraceRegs) Packed() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (p *PtraceRegs) MarshalUnsafe(dst []byte) []byte {
|
||||
size := p.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(p), uintptr(size))
|
||||
return dst[size:]
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (p *PtraceRegs) UnmarshalUnsafe(src []byte) []byte {
|
||||
size := p.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(p), unsafe.Pointer(&src[0]), uintptr(size))
|
||||
return src[size:]
|
||||
}
|
||||
|
||||
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||
func (p *PtraceRegs) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||
hdr.Len = p.SizeBytes()
|
||||
hdr.Cap = p.SizeBytes()
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||
func (p *PtraceRegs) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return p.CopyOutN(cc, addr, p.SizeBytes())
|
||||
}
|
||||
|
||||
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||
func (p *PtraceRegs) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||
hdr.Len = p.SizeBytes()
|
||||
hdr.Cap = p.SizeBytes()
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
func (p *PtraceRegs) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return p.CopyInN(cc, addr, p.SizeBytes())
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.WriteTo.
|
||||
func (p *PtraceRegs) WriteTo(writer io.Writer) (int64, error) {
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||
hdr.Len = p.SizeBytes()
|
||||
hdr.Cap = p.SizeBytes()
|
||||
|
||||
length, err := writer.Write(buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (s *SemidDS) SizeBytes() int {
|
||||
return 24 +
|
||||
(*IPCPerm)(nil).SizeBytes() +
|
||||
(*TimeT)(nil).SizeBytes() +
|
||||
(*TimeT)(nil).SizeBytes()
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (s *SemidDS) MarshalBytes(dst []byte) []byte {
|
||||
dst = s.SemPerm.MarshalUnsafe(dst)
|
||||
dst = s.SemOTime.MarshalUnsafe(dst)
|
||||
dst = s.SemCTime.MarshalUnsafe(dst)
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.SemNSems))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused3))
|
||||
dst = dst[8:]
|
||||
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused4))
|
||||
dst = dst[8:]
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (s *SemidDS) UnmarshalBytes(src []byte) []byte {
|
||||
src = s.SemPerm.UnmarshalUnsafe(src)
|
||||
src = s.SemOTime.UnmarshalUnsafe(src)
|
||||
src = s.SemCTime.UnmarshalUnsafe(src)
|
||||
s.SemNSems = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.unused3 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
s.unused4 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||
src = src[8:]
|
||||
return src
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
//
|
||||
//go:nosplit
|
||||
func (s *SemidDS) Packed() bool {
|
||||
return s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed()
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (s *SemidDS) MarshalUnsafe(dst []byte) []byte {
|
||||
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
size := s.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
|
||||
return dst[size:]
|
||||
}
|
||||
// Type SemidDS doesn't have a packed layout in memory, fallback to MarshalBytes.
|
||||
return s.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (s *SemidDS) UnmarshalUnsafe(src []byte) []byte {
|
||||
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
size := s.SizeBytes()
|
||||
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
|
||||
return src[size:]
|
||||
}
|
||||
// Type SemidDS doesn't have a packed layout in memory, fallback to UnmarshalBytes.
|
||||
return s.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||
func (s *SemidDS) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||
s.MarshalBytes(buf) // escapes: fallback.
|
||||
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||
func (s *SemidDS) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return s.CopyOutN(cc, addr, s.SizeBytes())
|
||||
}
|
||||
|
||||
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||
func (s *SemidDS) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
// Type SemidDS doesn't have a packed layout in memory, fall back to UnmarshalBytes.
|
||||
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Unmarshal unconditionally. If we had a short copy-in, this results in a
|
||||
// partially unmarshalled struct.
|
||||
s.UnmarshalBytes(buf) // escapes: fallback.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return length, err
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
func (s *SemidDS) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
return s.CopyInN(cc, addr, s.SizeBytes())
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.WriteTo.
|
||||
func (s *SemidDS) WriteTo(writer io.Writer) (int64, error) {
|
||||
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||
buf := make([]byte, s.SizeBytes())
|
||||
s.MarshalBytes(buf)
|
||||
length, err := writer.Write(buf)
|
||||
return int64(length), err
|
||||
}
|
||||
|
||||
// Construct a slice backed by dst's underlying memory.
|
||||
var buf []byte
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||
hdr.Len = s.SizeBytes()
|
||||
hdr.Cap = s.SizeBytes()
|
||||
|
||||
length, err := writer.Write(buf)
|
||||
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||
// must live until the use above.
|
||||
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||
return int64(length), err
|
||||
}
|
||||
50
pkg/abi/linux/linux_arm64_state_autogen.go
Normal file
50
pkg/abi/linux/linux_arm64_state_autogen.go
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
// automatically generated by stateify.
|
||||
|
||||
//go:build arm64 && arm64 && arm64 && arm64 && arm64
|
||||
// +build arm64,arm64,arm64,arm64,arm64
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/state"
|
||||
)
|
||||
|
||||
func (p *PtraceRegs) StateTypeName() string {
|
||||
return "pkg/abi/linux.PtraceRegs"
|
||||
}
|
||||
|
||||
func (p *PtraceRegs) StateFields() []string {
|
||||
return []string{
|
||||
"Regs",
|
||||
"Sp",
|
||||
"Pc",
|
||||
"Pstate",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PtraceRegs) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (p *PtraceRegs) StateSave(stateSinkObject state.Sink) {
|
||||
p.beforeSave()
|
||||
stateSinkObject.Save(0, &p.Regs)
|
||||
stateSinkObject.Save(1, &p.Sp)
|
||||
stateSinkObject.Save(2, &p.Pc)
|
||||
stateSinkObject.Save(3, &p.Pstate)
|
||||
}
|
||||
|
||||
func (p *PtraceRegs) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (p *PtraceRegs) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &p.Regs)
|
||||
stateSourceObject.Load(1, &p.Sp)
|
||||
stateSourceObject.Load(2, &p.Pc)
|
||||
stateSourceObject.Load(3, &p.Pstate)
|
||||
}
|
||||
|
||||
func init() {
|
||||
state.Register((*PtraceRegs)(nil))
|
||||
}
|
||||
599
pkg/abi/linux/linux_state_autogen.go
Normal file
599
pkg/abi/linux/linux_state_autogen.go
Normal file
|
|
@ -0,0 +1,599 @@
|
|||
// automatically generated by stateify.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/state"
|
||||
)
|
||||
|
||||
func (i *IOEvent) StateTypeName() string {
|
||||
return "pkg/abi/linux.IOEvent"
|
||||
}
|
||||
|
||||
func (i *IOEvent) StateFields() []string {
|
||||
return []string{
|
||||
"Data",
|
||||
"Obj",
|
||||
"Result",
|
||||
"Result2",
|
||||
}
|
||||
}
|
||||
|
||||
func (i *IOEvent) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IOEvent) StateSave(stateSinkObject state.Sink) {
|
||||
i.beforeSave()
|
||||
stateSinkObject.Save(0, &i.Data)
|
||||
stateSinkObject.Save(1, &i.Obj)
|
||||
stateSinkObject.Save(2, &i.Result)
|
||||
stateSinkObject.Save(3, &i.Result2)
|
||||
}
|
||||
|
||||
func (i *IOEvent) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IOEvent) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &i.Data)
|
||||
stateSourceObject.Load(1, &i.Obj)
|
||||
stateSourceObject.Load(2, &i.Result)
|
||||
stateSourceObject.Load(3, &i.Result2)
|
||||
}
|
||||
|
||||
func (b *BPFInstruction) StateTypeName() string {
|
||||
return "pkg/abi/linux.BPFInstruction"
|
||||
}
|
||||
|
||||
func (b *BPFInstruction) StateFields() []string {
|
||||
return []string{
|
||||
"OpCode",
|
||||
"JumpIfTrue",
|
||||
"JumpIfFalse",
|
||||
"K",
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BPFInstruction) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (b *BPFInstruction) StateSave(stateSinkObject state.Sink) {
|
||||
b.beforeSave()
|
||||
stateSinkObject.Save(0, &b.OpCode)
|
||||
stateSinkObject.Save(1, &b.JumpIfTrue)
|
||||
stateSinkObject.Save(2, &b.JumpIfFalse)
|
||||
stateSinkObject.Save(3, &b.K)
|
||||
}
|
||||
|
||||
func (b *BPFInstruction) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (b *BPFInstruction) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &b.OpCode)
|
||||
stateSourceObject.Load(1, &b.JumpIfTrue)
|
||||
stateSourceObject.Load(2, &b.JumpIfFalse)
|
||||
stateSourceObject.Load(3, &b.K)
|
||||
}
|
||||
|
||||
func (f *FUSEHeaderIn) StateTypeName() string {
|
||||
return "pkg/abi/linux.FUSEHeaderIn"
|
||||
}
|
||||
|
||||
func (f *FUSEHeaderIn) StateFields() []string {
|
||||
return []string{
|
||||
"Len",
|
||||
"Opcode",
|
||||
"Unique",
|
||||
"NodeID",
|
||||
"UID",
|
||||
"GID",
|
||||
"PID",
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FUSEHeaderIn) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (f *FUSEHeaderIn) StateSave(stateSinkObject state.Sink) {
|
||||
f.beforeSave()
|
||||
stateSinkObject.Save(0, &f.Len)
|
||||
stateSinkObject.Save(1, &f.Opcode)
|
||||
stateSinkObject.Save(2, &f.Unique)
|
||||
stateSinkObject.Save(3, &f.NodeID)
|
||||
stateSinkObject.Save(4, &f.UID)
|
||||
stateSinkObject.Save(5, &f.GID)
|
||||
stateSinkObject.Save(6, &f.PID)
|
||||
}
|
||||
|
||||
func (f *FUSEHeaderIn) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (f *FUSEHeaderIn) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &f.Len)
|
||||
stateSourceObject.Load(1, &f.Opcode)
|
||||
stateSourceObject.Load(2, &f.Unique)
|
||||
stateSourceObject.Load(3, &f.NodeID)
|
||||
stateSourceObject.Load(4, &f.UID)
|
||||
stateSourceObject.Load(5, &f.GID)
|
||||
stateSourceObject.Load(6, &f.PID)
|
||||
}
|
||||
|
||||
func (f *FUSEHeaderOut) StateTypeName() string {
|
||||
return "pkg/abi/linux.FUSEHeaderOut"
|
||||
}
|
||||
|
||||
func (f *FUSEHeaderOut) StateFields() []string {
|
||||
return []string{
|
||||
"Len",
|
||||
"Error",
|
||||
"Unique",
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FUSEHeaderOut) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (f *FUSEHeaderOut) StateSave(stateSinkObject state.Sink) {
|
||||
f.beforeSave()
|
||||
stateSinkObject.Save(0, &f.Len)
|
||||
stateSinkObject.Save(1, &f.Error)
|
||||
stateSinkObject.Save(2, &f.Unique)
|
||||
}
|
||||
|
||||
func (f *FUSEHeaderOut) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (f *FUSEHeaderOut) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &f.Len)
|
||||
stateSourceObject.Load(1, &f.Error)
|
||||
stateSourceObject.Load(2, &f.Unique)
|
||||
}
|
||||
|
||||
func (i *IOUringCqe) StateTypeName() string {
|
||||
return "pkg/abi/linux.IOUringCqe"
|
||||
}
|
||||
|
||||
func (i *IOUringCqe) StateFields() []string {
|
||||
return []string{
|
||||
"UserData",
|
||||
"Res",
|
||||
"Flags",
|
||||
}
|
||||
}
|
||||
|
||||
func (i *IOUringCqe) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IOUringCqe) StateSave(stateSinkObject state.Sink) {
|
||||
i.beforeSave()
|
||||
stateSinkObject.Save(0, &i.UserData)
|
||||
stateSinkObject.Save(1, &i.Res)
|
||||
stateSinkObject.Save(2, &i.Flags)
|
||||
}
|
||||
|
||||
func (i *IOUringCqe) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IOUringCqe) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &i.UserData)
|
||||
stateSourceObject.Load(1, &i.Res)
|
||||
stateSourceObject.Load(2, &i.Flags)
|
||||
}
|
||||
|
||||
func (i *IOUring) StateTypeName() string {
|
||||
return "pkg/abi/linux.IOUring"
|
||||
}
|
||||
|
||||
func (i *IOUring) StateFields() []string {
|
||||
return []string{
|
||||
"Head",
|
||||
"Tail",
|
||||
}
|
||||
}
|
||||
|
||||
func (i *IOUring) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IOUring) StateSave(stateSinkObject state.Sink) {
|
||||
i.beforeSave()
|
||||
stateSinkObject.Save(0, &i.Head)
|
||||
stateSinkObject.Save(1, &i.Tail)
|
||||
}
|
||||
|
||||
func (i *IOUring) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IOUring) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &i.Head)
|
||||
stateSourceObject.Load(1, &i.Tail)
|
||||
}
|
||||
|
||||
func (i *IORings) StateTypeName() string {
|
||||
return "pkg/abi/linux.IORings"
|
||||
}
|
||||
|
||||
func (i *IORings) StateFields() []string {
|
||||
return []string{
|
||||
"Sq",
|
||||
"Cq",
|
||||
"SqRingMask",
|
||||
"CqRingMask",
|
||||
"SqRingEntries",
|
||||
"CqRingEntries",
|
||||
"sqDropped",
|
||||
"sqFlags",
|
||||
"cqFlags",
|
||||
"CqOverflow",
|
||||
}
|
||||
}
|
||||
|
||||
func (i *IORings) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IORings) StateSave(stateSinkObject state.Sink) {
|
||||
i.beforeSave()
|
||||
stateSinkObject.Save(0, &i.Sq)
|
||||
stateSinkObject.Save(1, &i.Cq)
|
||||
stateSinkObject.Save(2, &i.SqRingMask)
|
||||
stateSinkObject.Save(3, &i.CqRingMask)
|
||||
stateSinkObject.Save(4, &i.SqRingEntries)
|
||||
stateSinkObject.Save(5, &i.CqRingEntries)
|
||||
stateSinkObject.Save(6, &i.sqDropped)
|
||||
stateSinkObject.Save(7, &i.sqFlags)
|
||||
stateSinkObject.Save(8, &i.cqFlags)
|
||||
stateSinkObject.Save(9, &i.CqOverflow)
|
||||
}
|
||||
|
||||
func (i *IORings) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IORings) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &i.Sq)
|
||||
stateSourceObject.Load(1, &i.Cq)
|
||||
stateSourceObject.Load(2, &i.SqRingMask)
|
||||
stateSourceObject.Load(3, &i.CqRingMask)
|
||||
stateSourceObject.Load(4, &i.SqRingEntries)
|
||||
stateSourceObject.Load(5, &i.CqRingEntries)
|
||||
stateSourceObject.Load(6, &i.sqDropped)
|
||||
stateSourceObject.Load(7, &i.sqFlags)
|
||||
stateSourceObject.Load(8, &i.cqFlags)
|
||||
stateSourceObject.Load(9, &i.CqOverflow)
|
||||
}
|
||||
|
||||
func (i *IOUringSqe) StateTypeName() string {
|
||||
return "pkg/abi/linux.IOUringSqe"
|
||||
}
|
||||
|
||||
func (i *IOUringSqe) StateFields() []string {
|
||||
return []string{
|
||||
"Opcode",
|
||||
"Flags",
|
||||
"IoPrio",
|
||||
"Fd",
|
||||
"OffOrAddrOrCmdOp",
|
||||
"AddrOrSpliceOff",
|
||||
"Len",
|
||||
"specialFlags",
|
||||
"UserData",
|
||||
"BufIndexOrGroup",
|
||||
"personality",
|
||||
"spliceFDOrFileIndex",
|
||||
"addr3",
|
||||
}
|
||||
}
|
||||
|
||||
func (i *IOUringSqe) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IOUringSqe) StateSave(stateSinkObject state.Sink) {
|
||||
i.beforeSave()
|
||||
stateSinkObject.Save(0, &i.Opcode)
|
||||
stateSinkObject.Save(1, &i.Flags)
|
||||
stateSinkObject.Save(2, &i.IoPrio)
|
||||
stateSinkObject.Save(3, &i.Fd)
|
||||
stateSinkObject.Save(4, &i.OffOrAddrOrCmdOp)
|
||||
stateSinkObject.Save(5, &i.AddrOrSpliceOff)
|
||||
stateSinkObject.Save(6, &i.Len)
|
||||
stateSinkObject.Save(7, &i.specialFlags)
|
||||
stateSinkObject.Save(8, &i.UserData)
|
||||
stateSinkObject.Save(9, &i.BufIndexOrGroup)
|
||||
stateSinkObject.Save(10, &i.personality)
|
||||
stateSinkObject.Save(11, &i.spliceFDOrFileIndex)
|
||||
stateSinkObject.Save(12, &i.addr3)
|
||||
}
|
||||
|
||||
func (i *IOUringSqe) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *IOUringSqe) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &i.Opcode)
|
||||
stateSourceObject.Load(1, &i.Flags)
|
||||
stateSourceObject.Load(2, &i.IoPrio)
|
||||
stateSourceObject.Load(3, &i.Fd)
|
||||
stateSourceObject.Load(4, &i.OffOrAddrOrCmdOp)
|
||||
stateSourceObject.Load(5, &i.AddrOrSpliceOff)
|
||||
stateSourceObject.Load(6, &i.Len)
|
||||
stateSourceObject.Load(7, &i.specialFlags)
|
||||
stateSourceObject.Load(8, &i.UserData)
|
||||
stateSourceObject.Load(9, &i.BufIndexOrGroup)
|
||||
stateSourceObject.Load(10, &i.personality)
|
||||
stateSourceObject.Load(11, &i.spliceFDOrFileIndex)
|
||||
stateSourceObject.Load(12, &i.addr3)
|
||||
}
|
||||
|
||||
func (s *SigAction) StateTypeName() string {
|
||||
return "pkg/abi/linux.SigAction"
|
||||
}
|
||||
|
||||
func (s *SigAction) StateFields() []string {
|
||||
return []string{
|
||||
"Handler",
|
||||
"Flags",
|
||||
"Restorer",
|
||||
"Mask",
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SigAction) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (s *SigAction) StateSave(stateSinkObject state.Sink) {
|
||||
s.beforeSave()
|
||||
stateSinkObject.Save(0, &s.Handler)
|
||||
stateSinkObject.Save(1, &s.Flags)
|
||||
stateSinkObject.Save(2, &s.Restorer)
|
||||
stateSinkObject.Save(3, &s.Mask)
|
||||
}
|
||||
|
||||
func (s *SigAction) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (s *SigAction) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &s.Handler)
|
||||
stateSourceObject.Load(1, &s.Flags)
|
||||
stateSourceObject.Load(2, &s.Restorer)
|
||||
stateSourceObject.Load(3, &s.Mask)
|
||||
}
|
||||
|
||||
func (s *SignalStack) StateTypeName() string {
|
||||
return "pkg/abi/linux.SignalStack"
|
||||
}
|
||||
|
||||
func (s *SignalStack) StateFields() []string {
|
||||
return []string{
|
||||
"Addr",
|
||||
"Flags",
|
||||
"Size",
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SignalStack) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (s *SignalStack) StateSave(stateSinkObject state.Sink) {
|
||||
s.beforeSave()
|
||||
stateSinkObject.Save(0, &s.Addr)
|
||||
stateSinkObject.Save(1, &s.Flags)
|
||||
stateSinkObject.Save(2, &s.Size)
|
||||
}
|
||||
|
||||
func (s *SignalStack) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (s *SignalStack) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &s.Addr)
|
||||
stateSourceObject.Load(1, &s.Flags)
|
||||
stateSourceObject.Load(2, &s.Size)
|
||||
}
|
||||
|
||||
func (s *SignalInfo) StateTypeName() string {
|
||||
return "pkg/abi/linux.SignalInfo"
|
||||
}
|
||||
|
||||
func (s *SignalInfo) StateFields() []string {
|
||||
return []string{
|
||||
"Signo",
|
||||
"Errno",
|
||||
"Code",
|
||||
"Fields",
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SignalInfo) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (s *SignalInfo) StateSave(stateSinkObject state.Sink) {
|
||||
s.beforeSave()
|
||||
stateSinkObject.Save(0, &s.Signo)
|
||||
stateSinkObject.Save(1, &s.Errno)
|
||||
stateSinkObject.Save(2, &s.Code)
|
||||
stateSinkObject.Save(3, &s.Fields)
|
||||
}
|
||||
|
||||
func (s *SignalInfo) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (s *SignalInfo) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &s.Signo)
|
||||
stateSourceObject.Load(1, &s.Errno)
|
||||
stateSourceObject.Load(2, &s.Code)
|
||||
stateSourceObject.Load(3, &s.Fields)
|
||||
}
|
||||
|
||||
func (c *ControlMessageIPPacketInfo) StateTypeName() string {
|
||||
return "pkg/abi/linux.ControlMessageIPPacketInfo"
|
||||
}
|
||||
|
||||
func (c *ControlMessageIPPacketInfo) StateFields() []string {
|
||||
return []string{
|
||||
"NIC",
|
||||
"LocalAddr",
|
||||
"DestinationAddr",
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ControlMessageIPPacketInfo) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (c *ControlMessageIPPacketInfo) StateSave(stateSinkObject state.Sink) {
|
||||
c.beforeSave()
|
||||
stateSinkObject.Save(0, &c.NIC)
|
||||
stateSinkObject.Save(1, &c.LocalAddr)
|
||||
stateSinkObject.Save(2, &c.DestinationAddr)
|
||||
}
|
||||
|
||||
func (c *ControlMessageIPPacketInfo) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (c *ControlMessageIPPacketInfo) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &c.NIC)
|
||||
stateSourceObject.Load(1, &c.LocalAddr)
|
||||
stateSourceObject.Load(2, &c.DestinationAddr)
|
||||
}
|
||||
|
||||
func (c *ControlMessageIPv6PacketInfo) StateTypeName() string {
|
||||
return "pkg/abi/linux.ControlMessageIPv6PacketInfo"
|
||||
}
|
||||
|
||||
func (c *ControlMessageIPv6PacketInfo) StateFields() []string {
|
||||
return []string{
|
||||
"Addr",
|
||||
"NIC",
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ControlMessageIPv6PacketInfo) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (c *ControlMessageIPv6PacketInfo) StateSave(stateSinkObject state.Sink) {
|
||||
c.beforeSave()
|
||||
stateSinkObject.Save(0, &c.Addr)
|
||||
stateSinkObject.Save(1, &c.NIC)
|
||||
}
|
||||
|
||||
func (c *ControlMessageIPv6PacketInfo) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (c *ControlMessageIPv6PacketInfo) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &c.Addr)
|
||||
stateSourceObject.Load(1, &c.NIC)
|
||||
}
|
||||
|
||||
func (i *ICMP6Filter) StateTypeName() string {
|
||||
return "pkg/abi/linux.ICMP6Filter"
|
||||
}
|
||||
|
||||
func (i *ICMP6Filter) StateFields() []string {
|
||||
return []string{
|
||||
"Filter",
|
||||
}
|
||||
}
|
||||
|
||||
func (i *ICMP6Filter) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *ICMP6Filter) StateSave(stateSinkObject state.Sink) {
|
||||
i.beforeSave()
|
||||
stateSinkObject.Save(0, &i.Filter)
|
||||
}
|
||||
|
||||
func (i *ICMP6Filter) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (i *ICMP6Filter) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &i.Filter)
|
||||
}
|
||||
|
||||
func (t *KernelTermios) StateTypeName() string {
|
||||
return "pkg/abi/linux.KernelTermios"
|
||||
}
|
||||
|
||||
func (t *KernelTermios) StateFields() []string {
|
||||
return []string{
|
||||
"InputFlags",
|
||||
"OutputFlags",
|
||||
"ControlFlags",
|
||||
"LocalFlags",
|
||||
"LineDiscipline",
|
||||
"ControlCharacters",
|
||||
"InputSpeed",
|
||||
"OutputSpeed",
|
||||
}
|
||||
}
|
||||
|
||||
func (t *KernelTermios) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (t *KernelTermios) StateSave(stateSinkObject state.Sink) {
|
||||
t.beforeSave()
|
||||
stateSinkObject.Save(0, &t.InputFlags)
|
||||
stateSinkObject.Save(1, &t.OutputFlags)
|
||||
stateSinkObject.Save(2, &t.ControlFlags)
|
||||
stateSinkObject.Save(3, &t.LocalFlags)
|
||||
stateSinkObject.Save(4, &t.LineDiscipline)
|
||||
stateSinkObject.Save(5, &t.ControlCharacters)
|
||||
stateSinkObject.Save(6, &t.InputSpeed)
|
||||
stateSinkObject.Save(7, &t.OutputSpeed)
|
||||
}
|
||||
|
||||
func (t *KernelTermios) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (t *KernelTermios) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &t.InputFlags)
|
||||
stateSourceObject.Load(1, &t.OutputFlags)
|
||||
stateSourceObject.Load(2, &t.ControlFlags)
|
||||
stateSourceObject.Load(3, &t.LocalFlags)
|
||||
stateSourceObject.Load(4, &t.LineDiscipline)
|
||||
stateSourceObject.Load(5, &t.ControlCharacters)
|
||||
stateSourceObject.Load(6, &t.InputSpeed)
|
||||
stateSourceObject.Load(7, &t.OutputSpeed)
|
||||
}
|
||||
|
||||
func (w *WindowSize) StateTypeName() string {
|
||||
return "pkg/abi/linux.WindowSize"
|
||||
}
|
||||
|
||||
func (w *WindowSize) StateFields() []string {
|
||||
return []string{
|
||||
"Rows",
|
||||
"Cols",
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WindowSize) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (w *WindowSize) StateSave(stateSinkObject state.Sink) {
|
||||
w.beforeSave()
|
||||
stateSinkObject.Save(0, &w.Rows)
|
||||
stateSinkObject.Save(1, &w.Cols)
|
||||
}
|
||||
|
||||
func (w *WindowSize) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (w *WindowSize) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &w.Rows)
|
||||
stateSourceObject.Load(1, &w.Cols)
|
||||
}
|
||||
|
||||
func init() {
|
||||
state.Register((*IOEvent)(nil))
|
||||
state.Register((*BPFInstruction)(nil))
|
||||
state.Register((*FUSEHeaderIn)(nil))
|
||||
state.Register((*FUSEHeaderOut)(nil))
|
||||
state.Register((*IOUringCqe)(nil))
|
||||
state.Register((*IOUring)(nil))
|
||||
state.Register((*IORings)(nil))
|
||||
state.Register((*IOUringSqe)(nil))
|
||||
state.Register((*SigAction)(nil))
|
||||
state.Register((*SignalStack)(nil))
|
||||
state.Register((*SignalInfo)(nil))
|
||||
state.Register((*ControlMessageIPPacketInfo)(nil))
|
||||
state.Register((*ControlMessageIPv6PacketInfo)(nil))
|
||||
state.Register((*ICMP6Filter)(nil))
|
||||
state.Register((*KernelTermios)(nil))
|
||||
state.Register((*WindowSize)(nil))
|
||||
}
|
||||
3
pkg/abi/linux/linux_unsafe_abi_autogen_unsafe.go
Normal file
3
pkg/abi/linux/linux_unsafe_abi_autogen_unsafe.go
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// Automatically generated marshal implementation. See tools/go_marshal.
|
||||
|
||||
package linux
|
||||
3
pkg/abi/linux/linux_unsafe_state_autogen.go
Normal file
3
pkg/abi/linux/linux_unsafe_state_autogen.go
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// automatically generated by stateify.
|
||||
|
||||
package linux
|
||||
34
pkg/abi/linux/membarrier.go
Normal file
34
pkg/abi/linux/membarrier.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// membarrier(2) commands, from include/uapi/linux/membarrier.h.
|
||||
const (
|
||||
MEMBARRIER_CMD_QUERY = 0
|
||||
MEMBARRIER_CMD_GLOBAL = (1 << 0)
|
||||
MEMBARRIER_CMD_GLOBAL_EXPEDITED = (1 << 1)
|
||||
MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = (1 << 2)
|
||||
MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3)
|
||||
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4)
|
||||
MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 5)
|
||||
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6)
|
||||
MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ = (1 << 7)
|
||||
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ = (1 << 8)
|
||||
)
|
||||
|
||||
// membarrier(2) flags, from include/uapi/linux/membarrier.h.
|
||||
const (
|
||||
MEMBARRIER_CMD_FLAG_CPU = (1 << 0)
|
||||
)
|
||||
160
pkg/abi/linux/mm.go
Normal file
160
pkg/abi/linux/mm.go
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Protections for mmap(2).
|
||||
const (
|
||||
PROT_NONE = 0
|
||||
PROT_READ = 1 << 0
|
||||
PROT_WRITE = 1 << 1
|
||||
PROT_EXEC = 1 << 2
|
||||
PROT_SEM = 1 << 3
|
||||
PROT_GROWSDOWN = 1 << 24
|
||||
PROT_GROWSUP = 1 << 25
|
||||
)
|
||||
|
||||
// Flags for mmap(2).
|
||||
const (
|
||||
MAP_SHARED = 1 << 0
|
||||
MAP_PRIVATE = 1 << 1
|
||||
MAP_DROPPABLE = 1 << 3
|
||||
MAP_FIXED = 1 << 4
|
||||
MAP_ANONYMOUS = 1 << 5
|
||||
MAP_32BIT = 1 << 6 // arch/x86/include/uapi/asm/mman.h
|
||||
MAP_GROWSDOWN = 1 << 8
|
||||
MAP_DENYWRITE = 1 << 11
|
||||
MAP_EXECUTABLE = 1 << 12
|
||||
MAP_LOCKED = 1 << 13
|
||||
MAP_NORESERVE = 1 << 14
|
||||
MAP_POPULATE = 1 << 15
|
||||
MAP_NONBLOCK = 1 << 16
|
||||
MAP_STACK = 1 << 17
|
||||
MAP_HUGETLB = 1 << 18
|
||||
)
|
||||
|
||||
// Flags for mremap(2).
|
||||
const (
|
||||
MREMAP_MAYMOVE = 1 << 0
|
||||
MREMAP_FIXED = 1 << 1
|
||||
)
|
||||
|
||||
// Flags for mlock2(2).
|
||||
const (
|
||||
MLOCK_ONFAULT = 0x01
|
||||
)
|
||||
|
||||
// Flags for mlockall(2).
|
||||
const (
|
||||
MCL_CURRENT = 1
|
||||
MCL_FUTURE = 2
|
||||
MCL_ONFAULT = 4
|
||||
)
|
||||
|
||||
// Advice for madvise(2).
|
||||
const (
|
||||
MADV_NORMAL = 0
|
||||
MADV_RANDOM = 1
|
||||
MADV_SEQUENTIAL = 2
|
||||
MADV_WILLNEED = 3
|
||||
MADV_DONTNEED = 4
|
||||
MADV_REMOVE = 9
|
||||
MADV_DONTFORK = 10
|
||||
MADV_DOFORK = 11
|
||||
MADV_MERGEABLE = 12
|
||||
MADV_UNMERGEABLE = 13
|
||||
MADV_HUGEPAGE = 14
|
||||
MADV_NOHUGEPAGE = 15
|
||||
MADV_DONTDUMP = 16
|
||||
MADV_DODUMP = 17
|
||||
MADV_HWPOISON = 100
|
||||
MADV_SOFT_OFFLINE = 101
|
||||
MADV_NOMAJFAULT = 200
|
||||
MADV_DONTCHGME = 201
|
||||
)
|
||||
|
||||
// Flags for msync(2).
|
||||
const (
|
||||
MS_ASYNC = 1 << 0
|
||||
MS_INVALIDATE = 1 << 1
|
||||
MS_SYNC = 1 << 2
|
||||
)
|
||||
|
||||
// NumaPolicy is the NUMA memory policy for a memory range. See numa(7).
|
||||
//
|
||||
// +marshal
|
||||
type NumaPolicy int32
|
||||
|
||||
// Policies for get_mempolicy(2)/set_mempolicy(2).
|
||||
const (
|
||||
MPOL_DEFAULT NumaPolicy = 0
|
||||
MPOL_PREFERRED NumaPolicy = 1
|
||||
MPOL_BIND NumaPolicy = 2
|
||||
MPOL_INTERLEAVE NumaPolicy = 3
|
||||
MPOL_LOCAL NumaPolicy = 4
|
||||
MPOL_MAX NumaPolicy = 5
|
||||
)
|
||||
|
||||
// Flags for get_mempolicy(2).
|
||||
const (
|
||||
MPOL_F_NODE = 1 << 0
|
||||
MPOL_F_ADDR = 1 << 1
|
||||
MPOL_F_MEMS_ALLOWED = 1 << 2
|
||||
)
|
||||
|
||||
// Flags for set_mempolicy(2).
|
||||
const (
|
||||
MPOL_F_RELATIVE_NODES = 1 << 14
|
||||
MPOL_F_STATIC_NODES = 1 << 15
|
||||
|
||||
MPOL_MODE_FLAGS = (MPOL_F_STATIC_NODES | MPOL_F_RELATIVE_NODES)
|
||||
)
|
||||
|
||||
// Flags for mbind(2).
|
||||
const (
|
||||
MPOL_MF_STRICT = 1 << 0
|
||||
MPOL_MF_MOVE = 1 << 1
|
||||
MPOL_MF_MOVE_ALL = 1 << 2
|
||||
|
||||
MPOL_MF_VALID = MPOL_MF_STRICT | MPOL_MF_MOVE | MPOL_MF_MOVE_ALL
|
||||
)
|
||||
|
||||
// TaskSize is the address space size.
|
||||
var TaskSize = func() uintptr {
|
||||
pageSize := uintptr(unix.Getpagesize())
|
||||
for _, s := range feasibleTaskSizes {
|
||||
// mmap returns ENOMEM if addr is greater than TASK_SIZE,
|
||||
// otherwise it returns EINVAL, because addr isn't aligned to
|
||||
// the page size.
|
||||
_, _, errno := unix.RawSyscall6(
|
||||
unix.SYS_MMAP,
|
||||
s-pageSize-1,
|
||||
512,
|
||||
uintptr(unix.PROT_NONE),
|
||||
uintptr(unix.MAP_ANONYMOUS|unix.MAP_PRIVATE|unix.MAP_FIXED), 0, 0)
|
||||
if errno == unix.EINVAL {
|
||||
return s
|
||||
}
|
||||
if errno != unix.ENOMEM {
|
||||
panic(fmt.Sprintf("mmap returned unexpected error: %d", errno))
|
||||
}
|
||||
}
|
||||
panic("None of the address space sizes could be successfully mmaped")
|
||||
}()
|
||||
33
pkg/abi/linux/mm_amd64.go
Normal file
33
pkg/abi/linux/mm_amd64.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2023 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build amd64
|
||||
// +build amd64
|
||||
|
||||
package linux
|
||||
|
||||
// TASK_SIZE can be one of two values, corresponding to 4-level and 5-level
|
||||
// paging.
|
||||
//
|
||||
// The array has to be sorted in decreasing order.
|
||||
var feasibleTaskSizes = []uintptr{0xfffffffffff000, 0x7ffffffff000}
|
||||
|
||||
// Page fault error codes
|
||||
const (
|
||||
X86_PF_PROT = 1 << iota
|
||||
X86_PF_WRITE
|
||||
X86_PF_USER
|
||||
X86_PF_RSVD
|
||||
X86_PF_INSTR
|
||||
)
|
||||
25
pkg/abi/linux/mm_arm64.go
Normal file
25
pkg/abi/linux/mm_arm64.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2023 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build arm64
|
||||
// +build arm64
|
||||
|
||||
package linux
|
||||
|
||||
// Only 4K page size is supported on arm64. In this case, TASK_SIZE can
|
||||
// be one of three values, corresponding to 3-level, 4-level and
|
||||
// 5-level paging.
|
||||
//
|
||||
// The array has to be sorted in decreasing order.
|
||||
var feasibleTaskSizes = []uintptr{1 << 52, 1 << 48, 1 << 39}
|
||||
55
pkg/abi/linux/mqueue.go
Normal file
55
pkg/abi/linux/mqueue.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2021 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Default values for POSIX message queues. Source:
|
||||
// include/linux/ipc_namespace.h
|
||||
const (
|
||||
DFLT_QUEUESMAX = 256
|
||||
MIN_MSGMAX = 1
|
||||
DFLT_MSG uint = 10
|
||||
DFLT_MSGMAX = 10
|
||||
HARD_MSGMAX = 65536
|
||||
MIN_MSGSIZEMAX = 128
|
||||
DFLT_MSGSIZE uint = 8192
|
||||
DFLT_MSGSIZEMAX = 8192
|
||||
HARD_MSGSIZEMAX = (16 * 1024 * 1024)
|
||||
)
|
||||
|
||||
// Maximum values for a message queue. Source: include/uapi/linux/mqueue.h
|
||||
const (
|
||||
MQ_PRIO_MAX = 32768
|
||||
MQ_BYTES_MAX = 819200
|
||||
)
|
||||
|
||||
// Codes used by mq_notify. Source: include/uapi/linux/mqueue.h
|
||||
const (
|
||||
NOTIFY_NONE = 0
|
||||
NOTIFY_WOKENUP = 1
|
||||
NOTIFY_REMOVED = 2
|
||||
|
||||
NOTIFY_COOKIE_LEN = 32
|
||||
)
|
||||
|
||||
// MqAttr is equivalent to struct mq_attr. Source: include/uapi/linux/mqueue.h
|
||||
//
|
||||
// +marshal
|
||||
type MqAttr struct {
|
||||
MqFlags int64 // Message queue flags.
|
||||
MqMaxmsg int64 // Maximum number of messages.
|
||||
MqMsgsize int64 // Maximum message size.
|
||||
MqCurmsgs int64 // Number of messages currently queued.
|
||||
_ [4]int64 // Ignored for input, zeroed for output.
|
||||
}
|
||||
108
pkg/abi/linux/msgqueue.go
Normal file
108
pkg/abi/linux/msgqueue.go
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
// Copyright 2021 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"github.com/sagernet/gvisor/pkg/marshal/primitive"
|
||||
)
|
||||
|
||||
// Linux-specific control commands. Source: include/uapi/linux/msg.h
|
||||
const (
|
||||
MSG_STAT = 11
|
||||
MSG_INFO = 12
|
||||
MSG_STAT_ANY = 13
|
||||
)
|
||||
|
||||
// msgrcv(2) options. Source: include/uapi/linux/msg.h
|
||||
const (
|
||||
MSG_NOERROR = 0o10000 // No error if message is too big.
|
||||
MSG_EXCEPT = 0o20000 // Receive any message except of specified type.
|
||||
MSG_COPY = 0o40000 // Copy (not remove) all queue messages.
|
||||
)
|
||||
|
||||
// System-wide limits for message queues. Source: include/uapi/linux/msg.h
|
||||
const (
|
||||
MSGMNI = 32000 // Maximum number of message queue identifiers.
|
||||
MSGMAX = 8192 // Maximum size of message (bytes).
|
||||
MSGMNB = 16384 // Default max size of a message queue.
|
||||
)
|
||||
|
||||
// System-wide limits. Unused. Source: include/uapi/linux/msg.h
|
||||
const (
|
||||
MSGPOOL = (MSGMNI * MSGMNB / 1024)
|
||||
MSGTQL = MSGMNB
|
||||
MSGMAP = MSGMNB
|
||||
MSGSSZ = 16
|
||||
|
||||
// MSGSEG is simplified due to the inexistance of a ternary operator.
|
||||
MSGSEG = 0xffff
|
||||
)
|
||||
|
||||
// MsqidDS is equivalent to struct msqid64_ds. Source:
|
||||
// include/uapi/asm-generic/shmbuf.h
|
||||
//
|
||||
// +marshal
|
||||
type MsqidDS struct {
|
||||
MsgPerm IPCPerm // IPC permissions.
|
||||
MsgStime TimeT // Last msgsnd time.
|
||||
MsgRtime TimeT // Last msgrcv time.
|
||||
MsgCtime TimeT // Last change time.
|
||||
MsgCbytes uint64 // Current number of bytes on the queue.
|
||||
MsgQnum uint64 // Number of messages in the queue.
|
||||
MsgQbytes uint64 // Max number of bytes in the queue.
|
||||
MsgLspid int32 // PID of last msgsnd.
|
||||
MsgLrpid int32 // PID of last msgrcv.
|
||||
unused4 uint64
|
||||
unused5 uint64
|
||||
}
|
||||
|
||||
// MsgBuf is equivalent to struct msgbuf. Source: include/uapi/linux/msg.h
|
||||
//
|
||||
// +marshal dynamic
|
||||
type MsgBuf struct {
|
||||
Type primitive.Int64
|
||||
Text primitive.ByteSlice
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (b *MsgBuf) SizeBytes() int {
|
||||
return b.Type.SizeBytes() + b.Text.SizeBytes()
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (b *MsgBuf) MarshalBytes(dst []byte) []byte {
|
||||
dst = b.Type.MarshalUnsafe(dst)
|
||||
return b.Text.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (b *MsgBuf) UnmarshalBytes(src []byte) []byte {
|
||||
src = b.Type.UnmarshalUnsafe(src)
|
||||
return b.Text.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
// MsgInfo is equivalent to struct msginfo. Source: include/uapi/linux/msg.h
|
||||
//
|
||||
// +marshal
|
||||
type MsgInfo struct {
|
||||
MsgPool int32
|
||||
MsgMap int32
|
||||
MsgMax int32
|
||||
MsgMnb int32
|
||||
MsgMni int32
|
||||
MsgSsz int32
|
||||
MsgTql int32
|
||||
MsgSeg uint16 `marshal:"unaligned"`
|
||||
}
|
||||
128
pkg/abi/linux/netdevice.go
Normal file
128
pkg/abi/linux/netdevice.go
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
const (
|
||||
// IFNAMSIZ is the size of the name field for IFReq.
|
||||
IFNAMSIZ = 16
|
||||
)
|
||||
|
||||
// IFReq is an interface request.
|
||||
//
|
||||
// +marshal
|
||||
type IFReq struct {
|
||||
// IFName is an encoded name, normally null-terminated. This should be
|
||||
// accessed via the Name and SetName functions.
|
||||
IFName [IFNAMSIZ]byte
|
||||
|
||||
// Data is the union of the following structures:
|
||||
//
|
||||
// struct sockaddr ifr_addr;
|
||||
// struct sockaddr ifr_dstaddr;
|
||||
// struct sockaddr ifr_broadaddr;
|
||||
// struct sockaddr ifr_netmask;
|
||||
// struct sockaddr ifr_hwaddr;
|
||||
// short ifr_flags;
|
||||
// int ifr_ifindex;
|
||||
// int ifr_metric;
|
||||
// int ifr_mtu;
|
||||
// struct ifmap ifr_map;
|
||||
// char ifr_slave[IFNAMSIZ];
|
||||
// char ifr_newname[IFNAMSIZ];
|
||||
// char *ifr_data;
|
||||
Data [24]byte
|
||||
}
|
||||
|
||||
// Name returns the name.
|
||||
func (ifr *IFReq) Name() string {
|
||||
for c := 0; c < len(ifr.IFName); c++ {
|
||||
if ifr.IFName[c] == 0 {
|
||||
return string(ifr.IFName[:c])
|
||||
}
|
||||
}
|
||||
return string(ifr.IFName[:])
|
||||
}
|
||||
|
||||
// SetName sets the name.
|
||||
func (ifr *IFReq) SetName(name string) {
|
||||
n := copy(ifr.IFName[:], []byte(name))
|
||||
clear(ifr.IFName[n:])
|
||||
}
|
||||
|
||||
// SizeOfIFReq is the binary size of an IFReq struct (40 bytes).
|
||||
var SizeOfIFReq = (*IFReq)(nil).SizeBytes()
|
||||
|
||||
// IFMap contains interface hardware parameters.
|
||||
type IFMap struct {
|
||||
MemStart uint64
|
||||
MemEnd uint64
|
||||
BaseAddr int16
|
||||
IRQ byte
|
||||
DMA byte
|
||||
Port byte
|
||||
_ [3]byte // Pad to sizeof(struct ifmap).
|
||||
}
|
||||
|
||||
// IFConf is used to return a list of interfaces and their addresses. See
|
||||
// netdevice(7) and struct ifconf for more detail on its use.
|
||||
//
|
||||
// +marshal
|
||||
type IFConf struct {
|
||||
Len int32
|
||||
_ [4]byte // Pad to sizeof(struct ifconf).
|
||||
Ptr uint64
|
||||
}
|
||||
|
||||
// SizeOfIFConf is the binary size of an IFConf struct (16 bytes).
|
||||
var SizeOfIFConf = (*IFConf)(nil).SizeBytes()
|
||||
|
||||
// EthtoolCmd is a marshallable type to be able to easily copyin the
|
||||
// the command for an SIOCETHTOOL ioctl.
|
||||
//
|
||||
// +marshal
|
||||
type EthtoolCmd uint32
|
||||
|
||||
const (
|
||||
// ETHTOOL_GFEATURES is the command to SIOCETHTOOL to query device
|
||||
// features.
|
||||
// See: <linux/ethtool.h>
|
||||
ETHTOOL_GFEATURES EthtoolCmd = 0x3a
|
||||
)
|
||||
|
||||
// EthtoolGFeatures is used to return a list of device features.
|
||||
// See: <linux/ethtool.h>
|
||||
//
|
||||
// +marshal
|
||||
type EthtoolGFeatures struct {
|
||||
Cmd uint32
|
||||
Size uint32
|
||||
}
|
||||
|
||||
// EthtoolGetFeaturesBlock is used to return state of upto 32 device
|
||||
// features.
|
||||
// See: <linux/ethtool.h>
|
||||
//
|
||||
// +marshal
|
||||
type EthtoolGetFeaturesBlock struct {
|
||||
Available uint32
|
||||
Requested uint32
|
||||
Active uint32
|
||||
NeverChanged uint32
|
||||
}
|
||||
|
||||
const (
|
||||
// LOOPBACK_IFINDEX is defined in include/net/flow.h.
|
||||
LOOPBACK_IFINDEX = 1
|
||||
)
|
||||
796
pkg/abi/linux/netfilter.go
Normal file
796
pkg/abi/linux/netfilter.go
Normal file
|
|
@ -0,0 +1,796 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"github.com/sagernet/gvisor/pkg/marshal"
|
||||
"github.com/sagernet/gvisor/pkg/marshal/primitive"
|
||||
)
|
||||
|
||||
// This file contains structures required to support netfilter, specifically
|
||||
// the iptables tool.
|
||||
|
||||
// Hooks into the network stack. These correspond to values in
|
||||
// include/uapi/linux/netfilter.h.
|
||||
const (
|
||||
NF_INET_PRE_ROUTING = 0
|
||||
NF_INET_LOCAL_IN = 1
|
||||
NF_INET_FORWARD = 2
|
||||
NF_INET_LOCAL_OUT = 3
|
||||
NF_INET_POST_ROUTING = 4
|
||||
NF_INET_NUMHOOKS = 5
|
||||
NF_INET_INGRESS = NF_INET_NUMHOOKS
|
||||
)
|
||||
|
||||
const (
|
||||
NF_NETDEV_INGRESS = iota
|
||||
NF_NETDEV_EGRESS
|
||||
NF_NETDEV_NUMHOOKS
|
||||
)
|
||||
|
||||
// Protocol families (address families). These correspond to values in
|
||||
// include/uapi/linux/netfilter.h.
|
||||
const (
|
||||
NFPROTO_UNSPEC = 0
|
||||
NFPROTO_INET = 1
|
||||
NFPROTO_IPV4 = 2
|
||||
NFPROTO_ARP = 3
|
||||
NFPROTO_NETDEV = 5
|
||||
NFPROTO_BRIDGE = 7
|
||||
NFPROTO_IPV6 = 10
|
||||
)
|
||||
|
||||
// Verdicts that can be returned by targets. These correspond to values in
|
||||
// include/uapi/linux/netfilter.h
|
||||
const (
|
||||
NF_DROP = 0
|
||||
NF_ACCEPT = 1
|
||||
NF_STOLEN = 2
|
||||
NF_QUEUE = 3
|
||||
NF_REPEAT = 4
|
||||
NF_STOP = 5
|
||||
NF_MAX_VERDICT = NF_STOP
|
||||
// NF_RETURN is defined in include/uapi/linux/netfilter/x_tables.h.
|
||||
NF_RETURN = -NF_REPEAT - 1
|
||||
)
|
||||
|
||||
// VerdictStrings maps int verdicts to the strings they represent. It is used
|
||||
// for debugging.
|
||||
var VerdictStrings = map[int32]string{
|
||||
-NF_DROP - 1: "DROP",
|
||||
-NF_ACCEPT - 1: "ACCEPT",
|
||||
-NF_QUEUE - 1: "QUEUE",
|
||||
NF_RETURN: "RETURN",
|
||||
}
|
||||
|
||||
// Socket options for SOL_SOCKET. These correspond to values in
|
||||
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||
const (
|
||||
IPT_BASE_CTL = 64
|
||||
IPT_SO_SET_REPLACE = IPT_BASE_CTL
|
||||
IPT_SO_SET_ADD_COUNTERS = IPT_BASE_CTL + 1
|
||||
IPT_SO_SET_MAX = IPT_SO_SET_ADD_COUNTERS
|
||||
|
||||
IPT_SO_GET_INFO = IPT_BASE_CTL
|
||||
IPT_SO_GET_ENTRIES = IPT_BASE_CTL + 1
|
||||
IPT_SO_GET_REVISION_MATCH = IPT_BASE_CTL + 2
|
||||
IPT_SO_GET_REVISION_TARGET = IPT_BASE_CTL + 3
|
||||
IPT_SO_GET_MAX = IPT_SO_GET_REVISION_TARGET
|
||||
)
|
||||
|
||||
// Socket option for SOL_IP. This corresponds to the value in
|
||||
// include/uapi/linux/netfilter_ipv4.h.
|
||||
const (
|
||||
SO_ORIGINAL_DST = 80
|
||||
)
|
||||
|
||||
// Name lengths. These correspond to values in
|
||||
// include/uapi/linux/netfilter/x_tables.h.
|
||||
const (
|
||||
XT_FUNCTION_MAXNAMELEN = 30
|
||||
XT_EXTENSION_MAXNAMELEN = 29
|
||||
XT_TABLE_MAXNAMELEN = 32
|
||||
)
|
||||
|
||||
// IPTEntry is an iptable rule. It corresponds to struct ipt_entry in
|
||||
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type IPTEntry struct {
|
||||
// IP is used to filter packets based on the IP header.
|
||||
IP IPTIP
|
||||
|
||||
// NFCache relates to kernel-internal caching and isn't used by
|
||||
// userspace.
|
||||
NFCache uint32
|
||||
|
||||
// TargetOffset is the byte offset from the beginning of this IPTEntry
|
||||
// to the start of the entry's target.
|
||||
TargetOffset uint16
|
||||
|
||||
// NextOffset is the byte offset from the beginning of this IPTEntry to
|
||||
// the start of the next entry. It is thus also the size of the entry.
|
||||
NextOffset uint16
|
||||
|
||||
// Comeback is a return pointer. It is not used by userspace.
|
||||
Comeback uint32
|
||||
|
||||
// Counters holds the packet and byte counts for this rule.
|
||||
Counters XTCounters
|
||||
|
||||
// Elems holds the data for all this rule's matches followed by the
|
||||
// target. It is variable length -- users have to iterate over any
|
||||
// matches and use TargetOffset and NextOffset to make sense of the
|
||||
// data.
|
||||
//
|
||||
// Elems is omitted here because it would cause IPTEntry to be an extra
|
||||
// byte larger (see http://www.catb.org/esr/structure-packing/).
|
||||
//
|
||||
// Elems [0]byte
|
||||
}
|
||||
|
||||
// SizeOfIPTEntry is the size of an IPTEntry.
|
||||
const SizeOfIPTEntry = 112
|
||||
|
||||
// KernelIPTEntry is identical to IPTEntry, but includes the Elems field.
|
||||
//
|
||||
// +marshal dynamic
|
||||
type KernelIPTEntry struct {
|
||||
Entry IPTEntry
|
||||
|
||||
// Elems holds the data for all this rule's matches followed by the
|
||||
// target. It is variable length -- users have to iterate over any
|
||||
// matches and use TargetOffset and NextOffset to make sense of the
|
||||
// data.
|
||||
Elems primitive.ByteSlice
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (ke *KernelIPTEntry) SizeBytes() int {
|
||||
return ke.Entry.SizeBytes() + ke.Elems.SizeBytes()
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (ke *KernelIPTEntry) MarshalBytes(dst []byte) []byte {
|
||||
dst = ke.Entry.MarshalUnsafe(dst)
|
||||
return ke.Elems.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (ke *KernelIPTEntry) UnmarshalBytes(src []byte) []byte {
|
||||
src = ke.Entry.UnmarshalUnsafe(src)
|
||||
return ke.Elems.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
var _ marshal.Marshallable = (*KernelIPTEntry)(nil)
|
||||
|
||||
// IPTIP contains information for matching a packet's IP header.
|
||||
// It corresponds to struct ipt_ip in
|
||||
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type IPTIP struct {
|
||||
// Src is the source IP address.
|
||||
Src InetAddr
|
||||
|
||||
// Dst is the destination IP address.
|
||||
Dst InetAddr
|
||||
|
||||
// SrcMask is the source IP mask.
|
||||
SrcMask InetAddr
|
||||
|
||||
// DstMask is the destination IP mask.
|
||||
DstMask InetAddr
|
||||
|
||||
// InputInterface is the input network interface.
|
||||
InputInterface [IFNAMSIZ]byte
|
||||
|
||||
// OutputInterface is the output network interface.
|
||||
OutputInterface [IFNAMSIZ]byte
|
||||
|
||||
// InputInterfaceMask is the input interface mask.
|
||||
InputInterfaceMask [IFNAMSIZ]byte
|
||||
|
||||
// OuputInterfaceMask is the output interface mask.
|
||||
OutputInterfaceMask [IFNAMSIZ]byte
|
||||
|
||||
// Protocol is the transport protocol.
|
||||
Protocol uint16
|
||||
|
||||
// Flags define matching behavior for the IP header.
|
||||
Flags uint8
|
||||
|
||||
// InverseFlags invert the meaning of fields in struct IPTIP. See the
|
||||
// IPT_INV_* flags.
|
||||
InverseFlags uint8
|
||||
}
|
||||
|
||||
// Flags in IPTIP.InverseFlags. Corresponding constants are in
|
||||
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||
const (
|
||||
// Invert the meaning of InputInterface.
|
||||
IPT_INV_VIA_IN = 0x01
|
||||
// Invert the meaning of OutputInterface.
|
||||
IPT_INV_VIA_OUT = 0x02
|
||||
// Unclear what this is, as no references to it exist in the kernel.
|
||||
IPT_INV_TOS = 0x04
|
||||
// Invert the meaning of Src.
|
||||
IPT_INV_SRCIP = 0x08
|
||||
// Invert the meaning of Dst.
|
||||
IPT_INV_DSTIP = 0x10
|
||||
// Invert the meaning of the IPT_F_FRAG flag.
|
||||
IPT_INV_FRAG = 0x20
|
||||
// Invert the meaning of the Protocol field.
|
||||
IPT_INV_PROTO = 0x40
|
||||
// Enable all flags.
|
||||
IPT_INV_MASK = 0x7F
|
||||
)
|
||||
|
||||
// SizeOfIPTIP is the size of an IPTIP.
|
||||
const SizeOfIPTIP = 84
|
||||
|
||||
// XTCounters holds packet and byte counts for a rule. It corresponds to struct
|
||||
// xt_counters in include/uapi/linux/netfilter/x_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type XTCounters struct {
|
||||
// Pcnt is the packet count.
|
||||
Pcnt uint64
|
||||
|
||||
// Bcnt is the byte count.
|
||||
Bcnt uint64
|
||||
}
|
||||
|
||||
// SizeOfXTCounters is the size of an XTCounters.
|
||||
const SizeOfXTCounters = 16
|
||||
|
||||
// XTEntryMatch holds a match for a rule. For example, a user using the
|
||||
// addrtype iptables match extension would put the data for that match into an
|
||||
// XTEntryMatch. iptables-extensions(8) has a list of possible matches.
|
||||
//
|
||||
// XTEntryMatch corresponds to struct xt_entry_match in
|
||||
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
|
||||
// exposing different data to the user and kernel, but this struct holds only
|
||||
// the user data.
|
||||
//
|
||||
// +marshal
|
||||
type XTEntryMatch struct {
|
||||
MatchSize uint16
|
||||
Name ExtensionName
|
||||
Revision uint8
|
||||
// Data is omitted here because it would cause XTEntryMatch to be an
|
||||
// extra byte larger (see http://www.catb.org/esr/structure-packing/).
|
||||
// Data [0]byte
|
||||
}
|
||||
|
||||
// SizeOfXTEntryMatch is the size of an XTEntryMatch.
|
||||
const SizeOfXTEntryMatch = 32
|
||||
|
||||
// KernelXTEntryMatch is identical to XTEntryMatch, but contains
|
||||
// variable-length Data field.
|
||||
type KernelXTEntryMatch struct {
|
||||
XTEntryMatch
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// XTGetRevision corresponds to xt_get_revision in
|
||||
// include/uapi/linux/netfilter/x_tables.h
|
||||
//
|
||||
// +marshal
|
||||
type XTGetRevision struct {
|
||||
Name ExtensionName
|
||||
Revision uint8
|
||||
}
|
||||
|
||||
// SizeOfXTGetRevision is the size of an XTGetRevision.
|
||||
const SizeOfXTGetRevision = 30
|
||||
|
||||
// XTEntryTarget holds a target for a rule. For example, it can specify that
|
||||
// packets matching the rule should DROP, ACCEPT, or use an extension target.
|
||||
// iptables-extension(8) has a list of possible targets.
|
||||
//
|
||||
// XTEntryTarget corresponds to struct xt_entry_target in
|
||||
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
|
||||
// exposing different data to the user and kernel, but this struct holds only
|
||||
// the user data.
|
||||
//
|
||||
// +marshal
|
||||
type XTEntryTarget struct {
|
||||
TargetSize uint16
|
||||
Name ExtensionName
|
||||
Revision uint8
|
||||
// Data is omitted here because it would cause XTEntryTarget to be an
|
||||
// extra byte larger (see http://www.catb.org/esr/structure-packing/).
|
||||
// Data [0]byte
|
||||
}
|
||||
|
||||
// SizeOfXTEntryTarget is the size of an XTEntryTarget.
|
||||
const SizeOfXTEntryTarget = 32
|
||||
|
||||
// KernelXTEntryTarget is identical to XTEntryTarget, but contains a
|
||||
// variable-length Data field.
|
||||
type KernelXTEntryTarget struct {
|
||||
XTEntryTarget
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// XTStandardTarget is a built-in target, one of ACCEPT, DROP, JUMP, QUEUE,
|
||||
// RETURN, or jump. It corresponds to struct xt_standard_target in
|
||||
// include/uapi/linux/netfilter/x_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type XTStandardTarget struct {
|
||||
Target XTEntryTarget
|
||||
// A positive verdict indicates a jump, and is the offset from the
|
||||
// start of the table to jump to. A negative value means one of the
|
||||
// other built-in targets.
|
||||
Verdict int32
|
||||
_ [4]byte
|
||||
}
|
||||
|
||||
// SizeOfXTStandardTarget is the size of an XTStandardTarget.
|
||||
const SizeOfXTStandardTarget = 40
|
||||
|
||||
// XTErrorTarget triggers an error when reached. It is also used to mark the
|
||||
// beginning of user-defined chains by putting the name of the chain in
|
||||
// ErrorName. It corresponds to struct xt_error_target in
|
||||
// include/uapi/linux/netfilter/x_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type XTErrorTarget struct {
|
||||
Target XTEntryTarget
|
||||
Name ErrorName
|
||||
_ [2]byte
|
||||
}
|
||||
|
||||
// SizeOfXTErrorTarget is the size of an XTErrorTarget.
|
||||
const SizeOfXTErrorTarget = 64
|
||||
|
||||
// Flag values for NfNATIPV4Range. The values indicate whether to map
|
||||
// protocol specific part(ports) or IPs. It corresponds to values in
|
||||
// include/uapi/linux/netfilter/nf_nat.h.
|
||||
const (
|
||||
NF_NAT_RANGE_MAP_IPS = 1 << 0
|
||||
NF_NAT_RANGE_PROTO_SPECIFIED = 1 << 1
|
||||
NF_NAT_RANGE_PROTO_RANDOM = 1 << 2
|
||||
NF_NAT_RANGE_PERSISTENT = 1 << 3
|
||||
NF_NAT_RANGE_PROTO_RANDOM_FULLY = 1 << 4
|
||||
NF_NAT_RANGE_PROTO_RANDOM_ALL = (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||
NF_NAT_RANGE_MASK = (NF_NAT_RANGE_MAP_IPS |
|
||||
NF_NAT_RANGE_PROTO_SPECIFIED | NF_NAT_RANGE_PROTO_RANDOM |
|
||||
NF_NAT_RANGE_PERSISTENT | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||
)
|
||||
|
||||
// NfNATIPV4Range corresponds to struct nf_nat_ipv4_range
|
||||
// in include/uapi/linux/netfilter/nf_nat.h. The fields are in
|
||||
// network byte order.
|
||||
//
|
||||
// +marshal
|
||||
type NfNATIPV4Range struct {
|
||||
Flags uint32
|
||||
MinIP [4]byte
|
||||
MaxIP [4]byte
|
||||
MinPort uint16
|
||||
MaxPort uint16
|
||||
}
|
||||
|
||||
// NfNATIPV4MultiRangeCompat corresponds to struct
|
||||
// nf_nat_ipv4_multi_range_compat in include/uapi/linux/netfilter/nf_nat.h.
|
||||
//
|
||||
// +marshal
|
||||
type NfNATIPV4MultiRangeCompat struct {
|
||||
RangeSize uint32
|
||||
RangeIPV4 NfNATIPV4Range
|
||||
}
|
||||
|
||||
// XTRedirectTarget triggers a redirect when reached.
|
||||
// Adding 4 bytes of padding to make the struct 8 byte aligned.
|
||||
//
|
||||
// +marshal
|
||||
type XTRedirectTarget struct {
|
||||
Target XTEntryTarget
|
||||
NfRange NfNATIPV4MultiRangeCompat
|
||||
_ [4]byte
|
||||
}
|
||||
|
||||
// SizeOfXTRedirectTarget is the size of an XTRedirectTarget.
|
||||
const SizeOfXTRedirectTarget = 56
|
||||
|
||||
// XTNATTargetV0 triggers NAT when reached.
|
||||
// Adding 4 bytes of padding to make the struct 8 byte aligned.
|
||||
//
|
||||
// +marshal
|
||||
type XTNATTargetV0 struct {
|
||||
Target XTEntryTarget
|
||||
NfRange NfNATIPV4MultiRangeCompat
|
||||
_ [4]byte
|
||||
}
|
||||
|
||||
// SizeOfXTNATTargetV0 is the size of an XTNATTargetV0.
|
||||
const SizeOfXTNATTargetV0 = 56
|
||||
|
||||
// XTNATTargetV1 triggers NAT when reached.
|
||||
//
|
||||
// +marshal
|
||||
type XTNATTargetV1 struct {
|
||||
Target XTEntryTarget
|
||||
Range NFNATRange
|
||||
}
|
||||
|
||||
// SizeOfXTNATTargetV1 is the size of an XTNATTargetV1.
|
||||
const SizeOfXTNATTargetV1 = SizeOfXTEntryTarget + SizeOfNFNATRange
|
||||
|
||||
// XTNATTargetV2 triggers NAT when reached.
|
||||
//
|
||||
// +marshal
|
||||
type XTNATTargetV2 struct {
|
||||
Target XTEntryTarget
|
||||
Range NFNATRange2
|
||||
}
|
||||
|
||||
// SizeOfXTNATTargetV2 is the size of an XTNATTargetV2.
|
||||
const SizeOfXTNATTargetV2 = SizeOfXTEntryTarget + SizeOfNFNATRange2
|
||||
|
||||
// IPTGetinfo is the argument for the IPT_SO_GET_INFO sockopt. It corresponds
|
||||
// to struct ipt_getinfo in include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type IPTGetinfo struct {
|
||||
Name TableName
|
||||
ValidHooks uint32
|
||||
HookEntry [NF_INET_NUMHOOKS]uint32
|
||||
Underflow [NF_INET_NUMHOOKS]uint32
|
||||
NumEntries uint32
|
||||
Size uint32
|
||||
}
|
||||
|
||||
// SizeOfIPTGetinfo is the size of an IPTGetinfo.
|
||||
const SizeOfIPTGetinfo = 84
|
||||
|
||||
// IPTGetEntries is the argument for the IPT_SO_GET_ENTRIES sockopt. It
|
||||
// corresponds to struct ipt_get_entries in
|
||||
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type IPTGetEntries struct {
|
||||
Name TableName
|
||||
Size uint32
|
||||
_ [4]byte
|
||||
// Entrytable is omitted here because it would cause IPTGetEntries to
|
||||
// be an extra byte longer (see
|
||||
// http://www.catb.org/esr/structure-packing/).
|
||||
// Entrytable [0]IPTEntry
|
||||
}
|
||||
|
||||
// SizeOfIPTGetEntries is the size of an IPTGetEntries.
|
||||
const SizeOfIPTGetEntries = 40
|
||||
|
||||
// KernelIPTGetEntries is identical to IPTGetEntries, but includes the
|
||||
// Entrytable field.
|
||||
//
|
||||
// +marshal dynamic
|
||||
type KernelIPTGetEntries struct {
|
||||
IPTGetEntries
|
||||
Entrytable []KernelIPTEntry
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (ke *KernelIPTGetEntries) SizeBytes() int {
|
||||
res := ke.IPTGetEntries.SizeBytes()
|
||||
for _, entry := range ke.Entrytable {
|
||||
res += entry.SizeBytes()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (ke *KernelIPTGetEntries) MarshalBytes(dst []byte) []byte {
|
||||
dst = ke.IPTGetEntries.MarshalUnsafe(dst)
|
||||
for i := range ke.Entrytable {
|
||||
dst = ke.Entrytable[i].MarshalBytes(dst)
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (ke *KernelIPTGetEntries) UnmarshalBytes(src []byte) []byte {
|
||||
src = ke.IPTGetEntries.UnmarshalUnsafe(src)
|
||||
for i := range ke.Entrytable {
|
||||
src = ke.Entrytable[i].UnmarshalBytes(src)
|
||||
}
|
||||
return src
|
||||
}
|
||||
|
||||
var _ marshal.Marshallable = (*KernelIPTGetEntries)(nil)
|
||||
|
||||
// IPTReplace is the argument for the IPT_SO_SET_REPLACE sockopt. It
|
||||
// corresponds to struct ipt_replace in
|
||||
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type IPTReplace struct {
|
||||
Name TableName
|
||||
ValidHooks uint32
|
||||
NumEntries uint32
|
||||
Size uint32
|
||||
HookEntry [NF_INET_NUMHOOKS]uint32
|
||||
Underflow [NF_INET_NUMHOOKS]uint32
|
||||
NumCounters uint32
|
||||
Counters uint64 // This is really a *XTCounters.
|
||||
// Entries is omitted here because it would cause IPTReplace to be an
|
||||
// extra byte longer (see http://www.catb.org/esr/structure-packing/).
|
||||
// Entries [0]IPTEntry
|
||||
}
|
||||
|
||||
// SizeOfIPTReplace is the size of an IPTReplace.
|
||||
const SizeOfIPTReplace = 96
|
||||
|
||||
// ExtensionName holds the name of a netfilter extension.
|
||||
//
|
||||
// +marshal
|
||||
type ExtensionName [XT_EXTENSION_MAXNAMELEN]byte
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (en ExtensionName) String() string {
|
||||
return goString(en[:])
|
||||
}
|
||||
|
||||
// TableName holds the name of a netfilter table.
|
||||
//
|
||||
// +marshal
|
||||
type TableName [XT_TABLE_MAXNAMELEN]byte
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (tn TableName) String() string {
|
||||
return goString(tn[:])
|
||||
}
|
||||
|
||||
// ErrorName holds the name of a netfilter error. These can also hold
|
||||
// user-defined chains.
|
||||
//
|
||||
// +marshal
|
||||
type ErrorName [XT_FUNCTION_MAXNAMELEN]byte
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (en ErrorName) String() string {
|
||||
return goString(en[:])
|
||||
}
|
||||
|
||||
func goString(cstring []byte) string {
|
||||
for i, c := range cstring {
|
||||
if c == 0 {
|
||||
return string(cstring[:i])
|
||||
}
|
||||
}
|
||||
return string(cstring)
|
||||
}
|
||||
|
||||
// XTTCP holds data for matching TCP packets. It corresponds to struct xt_tcp
|
||||
// in include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||
//
|
||||
// +marshal
|
||||
type XTTCP struct {
|
||||
// SourcePortStart specifies the inclusive start of the range of source
|
||||
// ports to which the matcher applies.
|
||||
SourcePortStart uint16
|
||||
|
||||
// SourcePortEnd specifies the inclusive end of the range of source ports
|
||||
// to which the matcher applies.
|
||||
SourcePortEnd uint16
|
||||
|
||||
// DestinationPortStart specifies the start of the destination port
|
||||
// range to which the matcher applies.
|
||||
DestinationPortStart uint16
|
||||
|
||||
// DestinationPortEnd specifies the end of the destination port
|
||||
// range to which the matcher applies.
|
||||
DestinationPortEnd uint16
|
||||
|
||||
// Option specifies that a particular TCP option must be set.
|
||||
Option uint8
|
||||
|
||||
// FlagMask masks TCP flags when comparing to the FlagCompare byte. It allows
|
||||
// for specification of which flags are important to the matcher.
|
||||
FlagMask uint8
|
||||
|
||||
// FlagCompare, in combination with FlagMask, is used to match only packets
|
||||
// that have certain flags set.
|
||||
FlagCompare uint8
|
||||
|
||||
// InverseFlags flips the meaning of certain fields. See the
|
||||
// TX_TCP_INV_* flags.
|
||||
InverseFlags uint8
|
||||
}
|
||||
|
||||
// SizeOfXTTCP is the size of an XTTCP.
|
||||
const SizeOfXTTCP = 12
|
||||
|
||||
// Flags in XTTCP.InverseFlags. Corresponding constants are in
|
||||
// include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||
const (
|
||||
// Invert the meaning of SourcePortStart/End.
|
||||
XT_TCP_INV_SRCPT = 0x01
|
||||
// Invert the meaning of DestinationPortStart/End.
|
||||
XT_TCP_INV_DSTPT = 0x02
|
||||
// Invert the meaning of FlagCompare.
|
||||
XT_TCP_INV_FLAGS = 0x04
|
||||
// Invert the meaning of Option.
|
||||
XT_TCP_INV_OPTION = 0x08
|
||||
// Enable all flags.
|
||||
XT_TCP_INV_MASK = 0x0F
|
||||
)
|
||||
|
||||
// XTUDP holds data for matching UDP packets. It corresponds to struct xt_udp
|
||||
// in include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||
//
|
||||
// +marshal
|
||||
type XTUDP struct {
|
||||
// SourcePortStart is the inclusive start of the range of source ports
|
||||
// to which the matcher applies.
|
||||
SourcePortStart uint16
|
||||
|
||||
// SourcePortEnd is the inclusive end of the range of source ports to
|
||||
// which the matcher applies.
|
||||
SourcePortEnd uint16
|
||||
|
||||
// DestinationPortStart is the inclusive start of the destination port
|
||||
// range to which the matcher applies.
|
||||
DestinationPortStart uint16
|
||||
|
||||
// DestinationPortEnd is the inclusive end of the destination port
|
||||
// range to which the matcher applies.
|
||||
DestinationPortEnd uint16
|
||||
|
||||
// InverseFlags flips the meaning of certain fields. See the
|
||||
// TX_UDP_INV_* flags.
|
||||
InverseFlags uint8
|
||||
|
||||
_ uint8
|
||||
}
|
||||
|
||||
// SizeOfXTUDP is the size of an XTUDP.
|
||||
const SizeOfXTUDP = 10
|
||||
|
||||
// Flags in XTUDP.InverseFlags. Corresponding constants are in
|
||||
// include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||
const (
|
||||
// Invert the meaning of SourcePortStart/End.
|
||||
XT_UDP_INV_SRCPT = 0x01
|
||||
// Invert the meaning of DestinationPortStart/End.
|
||||
XT_UDP_INV_DSTPT = 0x02
|
||||
// Enable all flags.
|
||||
XT_UDP_INV_MASK = 0x03
|
||||
)
|
||||
|
||||
// IPTOwnerInfo holds data for matching packets with the owner v0 matcher. It
|
||||
// corresponds to struct ipt_owner_info in libxt_owner.c of iptables binary.
|
||||
//
|
||||
// +marshal
|
||||
type IPTOwnerInfo struct {
|
||||
// UID is user id which created the packet.
|
||||
UID uint32
|
||||
|
||||
// GID is group id which created the packet.
|
||||
GID uint32
|
||||
|
||||
// PID is process id of the process which created the packet.
|
||||
PID uint32
|
||||
|
||||
// SID is session id which created the packet.
|
||||
SID uint32
|
||||
|
||||
// Comm is the command name which created the packet.
|
||||
Comm [16]byte
|
||||
|
||||
// Match is used to match UID/GID of the socket. See the
|
||||
// XT_OWNER_* flags below.
|
||||
Match uint8
|
||||
|
||||
// Invert flips the meaning of Match field.
|
||||
Invert uint8 `marshal:"unaligned"`
|
||||
}
|
||||
|
||||
// SizeOfIPTOwnerInfo is the size of an IPTOwnerInfo.
|
||||
const SizeOfIPTOwnerInfo = 34
|
||||
|
||||
// XTOwnerMatchInfo holds data for matching packets with the owner v1 matcher.
|
||||
// It corresponds to struct xt_owner_match_info in
|
||||
// include/uapi/linux/netfilter/xt_owner.h
|
||||
//
|
||||
// +marshal
|
||||
type XTOwnerMatchInfo struct {
|
||||
UIDMin uint32
|
||||
UIDMax uint32
|
||||
GIDMin uint32
|
||||
GIDMax uint32
|
||||
Match uint8
|
||||
Invert uint8
|
||||
_ [2]byte
|
||||
}
|
||||
|
||||
// SizeOfXTOwnerMatchInfo is the size of an XTOwnerMatchInfo.
|
||||
const SizeOfXTOwnerMatchInfo = 20
|
||||
|
||||
// Flags in IPTOwnerInfo.Match and XTOwnerMatchInfo.Match. Corresponding
|
||||
// constants are in include/uapi/linux/netfilter/xt_owner.h.
|
||||
const (
|
||||
// Match the UID of the packet.
|
||||
XT_OWNER_UID = 1 << 0
|
||||
// Match the GID of the packet.
|
||||
XT_OWNER_GID = 1 << 1
|
||||
// Match if the socket exists for the packet. Forwarded
|
||||
// packets do not have an associated socket.
|
||||
XT_OWNER_SOCKET = 1 << 2
|
||||
)
|
||||
|
||||
// XT_MULTI_PORTS is the maximum number of ports that the
|
||||
// multiport match can handle.
|
||||
const XT_MULTI_PORTS = 15
|
||||
|
||||
// Flags in XTMultiport{,V1}.Flags; values from "enum xt_multiport_flags"
|
||||
// in "include/uapi/linux/netfilter/xt_multiport.h".
|
||||
const (
|
||||
XT_MULTIPORT_SOURCE uint8 = 0x0 // Match against source ports.
|
||||
XT_MULTIPORT_DESTINATION uint8 = 0x1 // Match against destination ports.
|
||||
XT_MULTIPORT_EITHER uint8 = 0x2 // Match against either ports.
|
||||
)
|
||||
|
||||
// XTMultiport holds data for matching packets against a set
|
||||
// of ports. It corresponds to "struct xt_multiport" defined
|
||||
// in "include/uapi/linux/netfilter/xt_multiport.h".
|
||||
//
|
||||
// +marshal
|
||||
type XTMultiport struct {
|
||||
// Flags indicates whether the match applies to
|
||||
// source ports, destination ports, or either, as
|
||||
// defined by "enum xt_multiport_flags".
|
||||
Flags uint8
|
||||
|
||||
// Count is the number of ports in the "Ports"
|
||||
// slice that the match will check. It must be
|
||||
// between 1 and "XT_MULTI_PORTS" (inclusive).
|
||||
Count uint8
|
||||
|
||||
// Ports is the set of ports that will be matched.
|
||||
// Only the first "Count" entries are considered.
|
||||
Ports [XT_MULTI_PORTS]uint16
|
||||
}
|
||||
|
||||
// XTMultiportV1 holds data for matching packets against a set
|
||||
// of ports. It corresponds to "struct xt_multiport_v1" defined
|
||||
// in "include/uapi/linux/netfilter/xt_multiport.h".
|
||||
//
|
||||
// +marshal
|
||||
type XTMultiportV1 struct {
|
||||
// Fields same as "XTMultiport".
|
||||
Flags uint8
|
||||
Count uint8
|
||||
Ports [XT_MULTI_PORTS]uint16
|
||||
|
||||
// Pflags is an array of port-specific flags. Each entry
|
||||
// in "Pflags" corresponds to the port at the same index
|
||||
// in "Ports".
|
||||
Pflags [XT_MULTI_PORTS]uint8
|
||||
|
||||
// Invert is a flag that, if nonzero, indicates
|
||||
// that the match result should be inverted.
|
||||
Invert uint8
|
||||
}
|
||||
|
||||
// SizeOfXTMultiport is the size of XTMultiport (in bytes).
|
||||
const SizeOfXTMultiport = 2 + (XT_MULTI_PORTS * 2)
|
||||
|
||||
// SizeOfXTMultiportV1 is the size of XTMultiportV1 (in bytes).
|
||||
const SizeOfXTMultiportV1 = SizeOfXTMultiport + XT_MULTI_PORTS + 1
|
||||
24
pkg/abi/linux/netfilter_arp.go
Normal file
24
pkg/abi/linux/netfilter_arp.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2025 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// These constants show the hooks ARP packets can be evaluated at.
|
||||
// From include/uapi/linux/netfilter_arp.h.
|
||||
const (
|
||||
NF_ARP_IN = iota
|
||||
NF_ARP_OUT
|
||||
NF_ARP_FORWARD
|
||||
NF_ARP_NUMHOOKS
|
||||
)
|
||||
41
pkg/abi/linux/netfilter_bridge.go
Normal file
41
pkg/abi/linux/netfilter_bridge.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2024 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import "math"
|
||||
|
||||
// Netfilter Bridge Standard Hook Points, from uapi/linux/netfilter_bridge.h.
|
||||
const (
|
||||
NF_BR_PRE_ROUTING = iota
|
||||
NF_BR_LOCAL_IN
|
||||
NF_BR_FORWARD
|
||||
NF_BR_LOCAL_OUT
|
||||
NF_BR_POST_ROUTING
|
||||
NF_BR_BROUTING
|
||||
NF_BR_NUMHOOKS
|
||||
)
|
||||
|
||||
// Netfilter Bridge Standard Hook Priorities, from
|
||||
// uapi/linux/netfilter_bridge.h.
|
||||
const (
|
||||
NF_BR_PRI_FIRST = math.MinInt
|
||||
NF_BR_PRI_NAT_DST_BRIDGED = -300
|
||||
NF_BR_PRI_FILTER_BRIDGED = -200
|
||||
NF_BR_PRI_BRNF = 0
|
||||
NF_BR_PRI_NAT_DST_OTHER = 100
|
||||
NF_BR_PRI_FILTER_OTHER = 200
|
||||
NF_BR_PRI_NAT_SRC = 300
|
||||
NF_BR_PRI_LAST = math.MaxInt
|
||||
)
|
||||
36
pkg/abi/linux/netfilter_ipv4.go
Normal file
36
pkg/abi/linux/netfilter_ipv4.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2024 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import "math"
|
||||
|
||||
// Netfilter IPv4 Standard Hook Priorities, from uapi/linux/netfilter_ipv4.h.
|
||||
const (
|
||||
NF_IP_PRI_FIRST = math.MinInt
|
||||
NF_IP_PRI_RAW_BEFORE_DEFRAG = -450
|
||||
NF_IP_PRI_CONNTRACK_DEFRAG = -400
|
||||
NF_IP_PRI_RAW = -300
|
||||
NF_IP_PRI_SELINUX_FIRST = -225
|
||||
NF_IP_PRI_CONNTRACK = -200
|
||||
NF_IP_PRI_MANGLE = -150
|
||||
NF_IP_PRI_NAT_DST = -100
|
||||
NF_IP_PRI_FILTER = 0
|
||||
NF_IP_PRI_SECURITY = 50
|
||||
NF_IP_PRI_NAT_SRC = 100
|
||||
NF_IP_PRI_SELINUX_LAST = 225
|
||||
NF_IP_PRI_CONNTRACK_HELPER = 300
|
||||
NF_IP_PRI_CONNTRACK_CONFIRM = math.MaxInt
|
||||
NF_IP_PRI_LAST = math.MaxInt
|
||||
)
|
||||
314
pkg/abi/linux/netfilter_ipv6.go
Normal file
314
pkg/abi/linux/netfilter_ipv6.go
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/marshal"
|
||||
"github.com/sagernet/gvisor/pkg/marshal/primitive"
|
||||
)
|
||||
|
||||
// This file contains structures required to support IPv6 netfilter and
|
||||
// ip6tables. Some constants and structs are equal to their IPv4 analogues, and
|
||||
// are only distinguished by context (e.g. whether used on an IPv4 of IPv6
|
||||
// socket).
|
||||
|
||||
// Netfilter IPv6 Standard Hook Priorities, from uapi/linux/netfilter_ipv6.h.
|
||||
const (
|
||||
NF_IP6_PRI_FIRST = math.MinInt
|
||||
NF_IP6_PRI_RAW_BEFORE_DEFRAG = -450
|
||||
NF_IP6_PRI_CONNTRACK_DEFRAG = -400
|
||||
NF_IP6_PRI_RAW = -300
|
||||
NF_IP6_PRI_SELINUX_FIRST = -225
|
||||
NF_IP6_PRI_CONNTRACK = -200
|
||||
NF_IP6_PRI_MANGLE = -150
|
||||
NF_IP6_PRI_NAT_DST = -100
|
||||
NF_IP6_PRI_FILTER = 0
|
||||
NF_IP6_PRI_SECURITY = 50
|
||||
NF_IP6_PRI_NAT_SRC = 100
|
||||
NF_IP6_PRI_SELINUX_LAST = 225
|
||||
NF_IP6_PRI_CONNTRACK_HELPER = 300
|
||||
NF_IP6_PRI_LAST = math.MaxInt
|
||||
)
|
||||
|
||||
// Socket options for SOL_SOCLET. These correspond to values in
|
||||
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||
const (
|
||||
IP6T_BASE_CTL = 64
|
||||
IP6T_SO_SET_REPLACE = IPT_BASE_CTL
|
||||
IP6T_SO_SET_ADD_COUNTERS = IPT_BASE_CTL + 1
|
||||
IP6T_SO_SET_MAX = IPT_SO_SET_ADD_COUNTERS
|
||||
|
||||
IP6T_SO_GET_INFO = IPT_BASE_CTL
|
||||
IP6T_SO_GET_ENTRIES = IPT_BASE_CTL + 1
|
||||
IP6T_SO_GET_REVISION_MATCH = IPT_BASE_CTL + 4
|
||||
IP6T_SO_GET_REVISION_TARGET = IPT_BASE_CTL + 5
|
||||
IP6T_SO_GET_MAX = IP6T_SO_GET_REVISION_TARGET
|
||||
)
|
||||
|
||||
// IP6T_ORIGINAL_DST is the ip6tables SOL_IPV6 socket option. Corresponds to
|
||||
// the value in include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||
const IP6T_ORIGINAL_DST = 80
|
||||
|
||||
// IP6TReplace is the argument for the IP6T_SO_SET_REPLACE sockopt. It
|
||||
// corresponds to struct ip6t_replace in
|
||||
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type IP6TReplace struct {
|
||||
Name TableName
|
||||
ValidHooks uint32
|
||||
NumEntries uint32
|
||||
Size uint32
|
||||
HookEntry [NF_INET_NUMHOOKS]uint32
|
||||
Underflow [NF_INET_NUMHOOKS]uint32
|
||||
NumCounters uint32
|
||||
Counters uint64 // This is really a *XTCounters.
|
||||
// Entries is omitted here because it would cause IP6TReplace to be an
|
||||
// extra byte longer (see http://www.catb.org/esr/structure-packing/).
|
||||
// Entries [0]IP6TEntry
|
||||
}
|
||||
|
||||
// SizeOfIP6TReplace is the size of an IP6TReplace.
|
||||
const SizeOfIP6TReplace = 96
|
||||
|
||||
// KernelIP6TGetEntries is identical to IP6TGetEntries, but includes the
|
||||
// Entrytable field.
|
||||
//
|
||||
// +marshal dynamic
|
||||
type KernelIP6TGetEntries struct {
|
||||
IPTGetEntries
|
||||
Entrytable []KernelIP6TEntry
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (ke *KernelIP6TGetEntries) SizeBytes() int {
|
||||
res := ke.IPTGetEntries.SizeBytes()
|
||||
for _, entry := range ke.Entrytable {
|
||||
res += entry.SizeBytes()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (ke *KernelIP6TGetEntries) MarshalBytes(dst []byte) []byte {
|
||||
dst = ke.IPTGetEntries.MarshalUnsafe(dst)
|
||||
for i := range ke.Entrytable {
|
||||
dst = ke.Entrytable[i].MarshalBytes(dst)
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (ke *KernelIP6TGetEntries) UnmarshalBytes(src []byte) []byte {
|
||||
src = ke.IPTGetEntries.UnmarshalUnsafe(src)
|
||||
for i := range ke.Entrytable {
|
||||
src = ke.Entrytable[i].UnmarshalBytes(src)
|
||||
}
|
||||
return src
|
||||
}
|
||||
|
||||
var _ marshal.Marshallable = (*KernelIP6TGetEntries)(nil)
|
||||
|
||||
// IP6TEntry is an iptables rule. It corresponds to struct ip6t_entry in
|
||||
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type IP6TEntry struct {
|
||||
// IPv6 is used to filter packets based on the IPv6 header.
|
||||
IPv6 IP6TIP
|
||||
|
||||
// NFCache relates to kernel-internal caching and isn't used by
|
||||
// userspace.
|
||||
NFCache uint32
|
||||
|
||||
// TargetOffset is the byte offset from the beginning of this IPTEntry
|
||||
// to the start of the entry's target.
|
||||
TargetOffset uint16
|
||||
|
||||
// NextOffset is the byte offset from the beginning of this IPTEntry to
|
||||
// the start of the next entry. It is thus also the size of the entry.
|
||||
NextOffset uint16
|
||||
|
||||
// Comeback is a return pointer. It is not used by userspace.
|
||||
Comeback uint32
|
||||
|
||||
_ [4]byte
|
||||
|
||||
// Counters holds the packet and byte counts for this rule.
|
||||
Counters XTCounters
|
||||
|
||||
// Elems holds the data for all this rule's matches followed by the
|
||||
// target. It is variable length -- users have to iterate over any
|
||||
// matches and use TargetOffset and NextOffset to make sense of the
|
||||
// data.
|
||||
//
|
||||
// Elems is omitted here because it would cause IPTEntry to be an extra
|
||||
// byte larger (see http://www.catb.org/esr/structure-packing/).
|
||||
//
|
||||
// Elems [0]byte
|
||||
}
|
||||
|
||||
// SizeOfIP6TEntry is the size of an IP6TEntry.
|
||||
const SizeOfIP6TEntry = 168
|
||||
|
||||
// KernelIP6TEntry is identical to IP6TEntry, but includes the Elems field.
|
||||
//
|
||||
// +marshal dynamic
|
||||
type KernelIP6TEntry struct {
|
||||
Entry IP6TEntry
|
||||
|
||||
// Elems holds the data for all this rule's matches followed by the
|
||||
// target. It is variable length -- users have to iterate over any
|
||||
// matches and use TargetOffset and NextOffset to make sense of the
|
||||
// data.
|
||||
Elems primitive.ByteSlice
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (ke *KernelIP6TEntry) SizeBytes() int {
|
||||
return ke.Entry.SizeBytes() + ke.Elems.SizeBytes()
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (ke *KernelIP6TEntry) MarshalBytes(dst []byte) []byte {
|
||||
dst = ke.Entry.MarshalUnsafe(dst)
|
||||
return ke.Elems.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (ke *KernelIP6TEntry) UnmarshalBytes(src []byte) []byte {
|
||||
src = ke.Entry.UnmarshalUnsafe(src)
|
||||
return ke.Elems.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
var _ marshal.Marshallable = (*KernelIP6TEntry)(nil)
|
||||
|
||||
// IP6TIP contains information for matching a packet's IP header.
|
||||
// It corresponds to struct ip6t_ip6 in
|
||||
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||
//
|
||||
// +marshal
|
||||
type IP6TIP struct {
|
||||
// Src is the source IP address.
|
||||
Src Inet6Addr
|
||||
|
||||
// Dst is the destination IP address.
|
||||
Dst Inet6Addr
|
||||
|
||||
// SrcMask is the source IP mask.
|
||||
SrcMask Inet6Addr
|
||||
|
||||
// DstMask is the destination IP mask.
|
||||
DstMask Inet6Addr
|
||||
|
||||
// InputInterface is the input network interface.
|
||||
InputInterface [IFNAMSIZ]byte
|
||||
|
||||
// OutputInterface is the output network interface.
|
||||
OutputInterface [IFNAMSIZ]byte
|
||||
|
||||
// InputInterfaceMask is the input interface mask.
|
||||
InputInterfaceMask [IFNAMSIZ]byte
|
||||
|
||||
// OuputInterfaceMask is the output interface mask.
|
||||
OutputInterfaceMask [IFNAMSIZ]byte
|
||||
|
||||
// Protocol is the transport protocol.
|
||||
Protocol uint16
|
||||
|
||||
// TOS matches TOS flags when Flags indicates filtering by TOS.
|
||||
TOS uint8
|
||||
|
||||
// Flags define matching behavior for the IP header.
|
||||
Flags uint8
|
||||
|
||||
// InverseFlags invert the meaning of fields in struct IPTIP. See the
|
||||
// IP6T_INV_* flags.
|
||||
InverseFlags uint8
|
||||
|
||||
// Linux defines in6_addr (Inet6Addr for us) as the union of a
|
||||
// 16-element byte array and a 4-element 32-bit integer array, so the
|
||||
// whole struct is 4-byte aligned.
|
||||
_ [3]byte
|
||||
}
|
||||
|
||||
// SizeOfIP6TIP is the size of an IP6 header.
|
||||
const SizeOfIP6TIP = 136
|
||||
|
||||
// Flags in IP6TIP.Flags. Corresponding constants are in
|
||||
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||
const (
|
||||
// Whether to check the Protocol field.
|
||||
IP6T_F_PROTO = 0x01
|
||||
// Whether to match the TOS field.
|
||||
IP6T_F_TOS = 0x02
|
||||
// Indicates that the jump target is an absolute GOTO, not an offset.
|
||||
IP6T_F_GOTO = 0x04
|
||||
// Enables all flags.
|
||||
IP6T_F_MASK = 0x07
|
||||
)
|
||||
|
||||
// Flags in IP6TIP.InverseFlags. Corresponding constants are in
|
||||
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||
const (
|
||||
// Invert the meaning of InputInterface.
|
||||
IP6T_INV_VIA_IN = 0x01
|
||||
// Invert the meaning of OutputInterface.
|
||||
IP6T_INV_VIA_OUT = 0x02
|
||||
// Invert the meaning of TOS.
|
||||
IP6T_INV_TOS = 0x04
|
||||
// Invert the meaning of Src.
|
||||
IP6T_INV_SRCIP = 0x08
|
||||
// Invert the meaning of Dst.
|
||||
IP6T_INV_DSTIP = 0x10
|
||||
// Invert the meaning of the IPT_F_FRAG flag.
|
||||
IP6T_INV_FRAG = 0x20
|
||||
// Enable all flags.
|
||||
IP6T_INV_MASK = 0x7F
|
||||
)
|
||||
|
||||
// NFNATRange corresponds to struct nf_nat_range in
|
||||
// include/uapi/linux/netfilter/nf_nat.h.
|
||||
//
|
||||
// +marshal
|
||||
type NFNATRange struct {
|
||||
Flags uint32
|
||||
MinAddr Inet6Addr
|
||||
MaxAddr Inet6Addr
|
||||
MinProto uint16 // Network byte order.
|
||||
MaxProto uint16 // Network byte order.
|
||||
}
|
||||
|
||||
// SizeOfNFNATRange is the size of NFNATRange.
|
||||
const SizeOfNFNATRange = 40
|
||||
|
||||
// NFNATRange2 corresponds to struct nf_nat_range2 in
|
||||
// include/uapi/linux/netfilter/nf_nat.h.
|
||||
//
|
||||
// +marshal
|
||||
type NFNATRange2 struct {
|
||||
Flags uint32
|
||||
MinAddr Inet6Addr
|
||||
MaxAddr Inet6Addr
|
||||
MinProto uint16 // Network byte order.
|
||||
MaxProto uint16 // Network byte order.
|
||||
BaseProto uint16 // Network byte order.
|
||||
_ [6]byte
|
||||
}
|
||||
|
||||
// SizeOfNFNATRange2 is the size of NFNATRange2.
|
||||
const SizeOfNFNATRange2 = 48
|
||||
159
pkg/abi/linux/netlink.go
Normal file
159
pkg/abi/linux/netlink.go
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Netlink protocols, from uapi/linux/netlink.h.
|
||||
const (
|
||||
NETLINK_ROUTE = 0
|
||||
NETLINK_UNUSED = 1
|
||||
NETLINK_USERSOCK = 2
|
||||
NETLINK_FIREWALL = 3
|
||||
NETLINK_SOCK_DIAG = 4
|
||||
NETLINK_NFLOG = 5
|
||||
NETLINK_XFRM = 6
|
||||
NETLINK_SELINUX = 7
|
||||
NETLINK_ISCSI = 8
|
||||
NETLINK_AUDIT = 9
|
||||
NETLINK_FIB_LOOKUP = 10
|
||||
NETLINK_CONNECTOR = 11
|
||||
NETLINK_NETFILTER = 12
|
||||
NETLINK_IP6_FW = 13
|
||||
NETLINK_DNRTMSG = 14
|
||||
NETLINK_KOBJECT_UEVENT = 15
|
||||
NETLINK_GENERIC = 16
|
||||
NETLINK_SCSITRANSPORT = 18
|
||||
NETLINK_ECRYPTFS = 19
|
||||
NETLINK_RDMA = 20
|
||||
NETLINK_CRYPTO = 21
|
||||
)
|
||||
|
||||
// SockAddrNetlink is struct sockaddr_nl, from uapi/linux/netlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type SockAddrNetlink struct {
|
||||
Family uint16
|
||||
_ uint16
|
||||
PortID uint32
|
||||
Groups uint32
|
||||
}
|
||||
|
||||
// SockAddrNetlinkSize is the size of SockAddrNetlink.
|
||||
const SockAddrNetlinkSize = 12
|
||||
|
||||
// NetlinkMessageHeader is struct nlmsghdr, from uapi/linux/netlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type NetlinkMessageHeader struct {
|
||||
Length uint32
|
||||
Type uint16
|
||||
Flags uint16
|
||||
Seq uint32
|
||||
PortID uint32
|
||||
}
|
||||
|
||||
// NetlinkMessageHeaderSize is the size of NetlinkMessageHeader.
|
||||
const NetlinkMessageHeaderSize = 16
|
||||
|
||||
// Netlink message header flag values, from uapi/linux/netlink.h.
|
||||
const (
|
||||
NLM_F_REQUEST = 0x1
|
||||
NLM_F_MULTI = 0x2
|
||||
NLM_F_ACK = 0x4
|
||||
NLM_F_ECHO = 0x8
|
||||
NLM_F_DUMP_INTR = 0x10
|
||||
)
|
||||
|
||||
// Netlink message header flags for GET requests, from uapi/linux/netlink.h.
|
||||
const (
|
||||
NLM_F_ROOT = 0x100
|
||||
NLM_F_MATCH = 0x200
|
||||
NLM_F_ATOMIC = 0x400
|
||||
NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH
|
||||
)
|
||||
|
||||
// Netlink message header flags for NEW requests, from uapi/linux/netlink.h.
|
||||
const (
|
||||
NLM_F_REPLACE = 0x100
|
||||
NLM_F_EXCL = 0x200
|
||||
NLM_F_CREATE = 0x400
|
||||
NLM_F_APPEND = 0x800
|
||||
)
|
||||
|
||||
// Netlink message header flags for DELETE requests, from uapi/linux/netlink.h.
|
||||
const (
|
||||
NLM_F_NONREC = 0x100
|
||||
NLM_F_BULK = 0x200
|
||||
)
|
||||
|
||||
// Standard netlink message types, from uapi/linux/netlink.h.
|
||||
const (
|
||||
NLMSG_NOOP = 0x1
|
||||
NLMSG_ERROR = 0x2
|
||||
NLMSG_DONE = 0x3
|
||||
NLMSG_OVERRUN = 0x4
|
||||
|
||||
// NLMSG_MIN_TYPE is the first value for protocol-level types.
|
||||
NLMSG_MIN_TYPE = 0x10
|
||||
)
|
||||
|
||||
// NLMSG_ALIGNTO is the alignment of netlink messages, from
|
||||
// uapi/linux/netlink.h.
|
||||
const NLMSG_ALIGNTO = 4
|
||||
|
||||
// NetlinkAttrHeader is the header of a netlink attribute, followed by payload.
|
||||
//
|
||||
// This is struct nlattr, from uapi/linux/netlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type NetlinkAttrHeader struct {
|
||||
Length uint16
|
||||
Type uint16
|
||||
}
|
||||
|
||||
// Netlink attribute flags, from uapi/linux/netlink.h.
|
||||
const (
|
||||
NLA_F_NESTED uint16 = 1 << 15
|
||||
NLA_F_NET_BYTEORDER = 1 << 14
|
||||
NLA_TYPE_MASK = ^(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
|
||||
)
|
||||
|
||||
// NetlinkAttrHeaderSize is the size of NetlinkAttrHeader.
|
||||
const NetlinkAttrHeaderSize = 4
|
||||
|
||||
// NLA_ALIGNTO is the alignment of netlink attributes, from
|
||||
// uapi/linux/netlink.h.
|
||||
const NLA_ALIGNTO = 4
|
||||
|
||||
// Socket options, from uapi/linux/netlink.h.
|
||||
const (
|
||||
NETLINK_ADD_MEMBERSHIP = 1
|
||||
NETLINK_DROP_MEMBERSHIP = 2
|
||||
NETLINK_PKTINFO = 3
|
||||
NETLINK_BROADCAST_ERROR = 4
|
||||
NETLINK_NO_ENOBUFS = 5
|
||||
NETLINK_LISTEN_ALL_NSID = 8
|
||||
NETLINK_LIST_MEMBERSHIPS = 9
|
||||
NETLINK_CAP_ACK = 10
|
||||
NETLINK_EXT_ACK = 11
|
||||
NETLINK_DUMP_STRICT_CHK = 12
|
||||
)
|
||||
|
||||
// NetlinkErrorMessage is struct nlmsgerr, from uapi/linux/netlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type NetlinkErrorMessage struct {
|
||||
Error int32
|
||||
Header NetlinkMessageHeader
|
||||
}
|
||||
92
pkg/abi/linux/netlink_netfilter.go
Normal file
92
pkg/abi/linux/netlink_netfilter.go
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright 2025 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Group describes Netlink Netfilter groups, from uapi/linux/netfilter/nfnetlink.h.
|
||||
// Users bind to specific groups to receive processing logs from those groups.
|
||||
type Group uint16
|
||||
|
||||
// Netlink Netfilter groups.
|
||||
const (
|
||||
NFNLGPR_NONE Group = iota
|
||||
NFNLGRP_CONNTRACK_NEW
|
||||
NFNLGRP_CONNTRACK_UPDATE
|
||||
NFNLGRP_CONNTRACK_DESTROY
|
||||
NFNLGRP_CONNTRACK_EXP_NEW
|
||||
NFNLGRP_CONNTRACK_EXP_UPDATE
|
||||
NFNLGRP_CONNTRACK_EXP_DESTROY
|
||||
NFNLGRP_NFTABLES
|
||||
NFNLGRP_ACCT_QUOTA
|
||||
NFNLGRP_NFTRACE
|
||||
__NFNLGRP_MAX
|
||||
NFNLGRP_MAX = __NFNLGRP_MAX - 1
|
||||
)
|
||||
|
||||
// NetFilterGenMsg describes the netlink netfilter genmsg message, from uapi/linux/netfilter/nfnetlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type NetFilterGenMsg struct {
|
||||
Family uint8
|
||||
Version uint8
|
||||
ResourceID uint16
|
||||
}
|
||||
|
||||
// SizeOfNetfilterGenMsg is the size of the netlink netfilter genmsg message.
|
||||
const SizeOfNetfilterGenMsg = 4
|
||||
|
||||
// NFNETLINK_V0 is the default version of the netlink netfilter.
|
||||
const NFNETLINK_V0 = 0
|
||||
|
||||
// Netlink Netfilter subsystem IDs, from uapi/linux/netfilter/nfnetlink.h.
|
||||
const (
|
||||
NFNL_SUBSYS_NONE = iota
|
||||
NFNL_SUBSYS_CTNETLINK
|
||||
NFNL_SUBSYS_CTNETLINK_EXP
|
||||
NFNL_SUBSYS_QUEUE
|
||||
NFNL_SUBSYS_ULOG
|
||||
NFNL_SUBSYS_OSF
|
||||
NFNL_SUBSYS_IPSET
|
||||
NFNL_SUBSYS_ACCT
|
||||
NFNL_SUBSYS_CTNETLINK_TIMEOUT
|
||||
NFNL_SUBSYS_CTHELPER
|
||||
NFNL_SUBSYS_NFTABLES
|
||||
NFNL_SUBSYS_NFT_COMPAT
|
||||
NFNL_SUBSYS_HOOK
|
||||
NFNL_SUBSYS_COUNT
|
||||
)
|
||||
|
||||
// NetFilterSubsysID returns the Netfilter Subsystem ID from the netlink message header.
|
||||
func (hdr *NetlinkMessageHeader) NetFilterSubsysID() uint16 {
|
||||
return (hdr.Type & 0xff00) >> 8
|
||||
}
|
||||
|
||||
// NetFilterMsgType returns the Netfilter Message Type from the netlink message header.
|
||||
func (hdr *NetlinkMessageHeader) NetFilterMsgType() NfTableMsgType {
|
||||
return NfTableMsgType(hdr.Type & 0x00ff)
|
||||
}
|
||||
|
||||
// Reserved control Netlink Netfilter messages, from uapi/linux/netfilter/nfnetlink.h.
|
||||
const (
|
||||
NFNL_MSG_BATCH_BEGIN = NLMSG_MIN_TYPE
|
||||
NFNL_MSG_BATCH_END = NLMSG_MIN_TYPE + 1
|
||||
)
|
||||
|
||||
// Netlink Netfilter batch attributes.
|
||||
const (
|
||||
NFNL_BATCH_UNSPEC = iota
|
||||
NFNL_BATCH_GENID
|
||||
__NFNL_BATCH_MAX
|
||||
NFNL_BATCH_MAX = __NFNL_BATCH_MAX - 1
|
||||
)
|
||||
377
pkg/abi/linux/netlink_route.go
Normal file
377
pkg/abi/linux/netlink_route.go
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Netlink message types for NETLINK_ROUTE sockets, from uapi/linux/rtnetlink.h.
|
||||
const (
|
||||
RTM_NEWLINK = 16
|
||||
RTM_DELLINK = 17
|
||||
RTM_GETLINK = 18
|
||||
RTM_SETLINK = 19
|
||||
|
||||
RTM_NEWADDR = 20
|
||||
RTM_DELADDR = 21
|
||||
RTM_GETADDR = 22
|
||||
|
||||
RTM_NEWROUTE = 24
|
||||
RTM_DELROUTE = 25
|
||||
RTM_GETROUTE = 26
|
||||
|
||||
RTM_NEWNEIGH = 28
|
||||
RTM_DELNEIGH = 29
|
||||
RTM_GETNEIGH = 30
|
||||
|
||||
RTM_NEWRULE = 32
|
||||
RTM_DELRULE = 33
|
||||
RTM_GETRULE = 34
|
||||
|
||||
RTM_NEWQDISC = 36
|
||||
RTM_DELQDISC = 37
|
||||
RTM_GETQDISC = 38
|
||||
|
||||
RTM_NEWTCLASS = 40
|
||||
RTM_DELTCLASS = 41
|
||||
RTM_GETTCLASS = 42
|
||||
|
||||
RTM_NEWTFILTER = 44
|
||||
RTM_DELTFILTER = 45
|
||||
RTM_GETTFILTER = 46
|
||||
|
||||
RTM_NEWACTION = 48
|
||||
RTM_DELACTION = 49
|
||||
RTM_GETACTION = 50
|
||||
|
||||
RTM_NEWPREFIX = 52
|
||||
|
||||
RTM_GETMULTICAST = 58
|
||||
|
||||
RTM_GETANYCAST = 62
|
||||
|
||||
RTM_NEWNEIGHTBL = 64
|
||||
RTM_GETNEIGHTBL = 66
|
||||
RTM_SETNEIGHTBL = 67
|
||||
|
||||
RTM_NEWNDUSEROPT = 68
|
||||
|
||||
RTM_NEWADDRLABEL = 72
|
||||
RTM_DELADDRLABEL = 73
|
||||
RTM_GETADDRLABEL = 74
|
||||
|
||||
RTM_GETDCB = 78
|
||||
RTM_SETDCB = 79
|
||||
|
||||
RTM_NEWNETCONF = 80
|
||||
RTM_GETNETCONF = 82
|
||||
|
||||
RTM_NEWMDB = 84
|
||||
RTM_DELMDB = 85
|
||||
RTM_GETMDB = 86
|
||||
|
||||
RTM_NEWNSID = 88
|
||||
RTM_DELNSID = 89
|
||||
RTM_GETNSID = 90
|
||||
)
|
||||
|
||||
// InterfaceInfoMessage is struct ifinfomsg, from uapi/linux/rtnetlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type InterfaceInfoMessage struct {
|
||||
Family uint8
|
||||
_ uint8
|
||||
Type uint16
|
||||
Index int32
|
||||
Flags uint32
|
||||
Change uint32
|
||||
}
|
||||
|
||||
// InterfaceInfoMessageSize is the size of InterfaceInfoMessage.
|
||||
const InterfaceInfoMessageSize = 16
|
||||
|
||||
// Interface flags, from uapi/linux/if.h.
|
||||
const (
|
||||
IFF_UP = 1 << 0
|
||||
IFF_BROADCAST = 1 << 1
|
||||
IFF_DEBUG = 1 << 2
|
||||
IFF_LOOPBACK = 1 << 3
|
||||
IFF_POINTOPOINT = 1 << 4
|
||||
IFF_NOTRAILERS = 1 << 5
|
||||
IFF_RUNNING = 1 << 6
|
||||
IFF_NOARP = 1 << 7
|
||||
IFF_PROMISC = 1 << 8
|
||||
IFF_ALLMULTI = 1 << 9
|
||||
IFF_MASTER = 1 << 10
|
||||
IFF_SLAVE = 1 << 11
|
||||
IFF_MULTICAST = 1 << 12
|
||||
IFF_PORTSEL = 1 << 13
|
||||
IFF_AUTOMEDIA = 1 << 14
|
||||
IFF_DYNAMIC = 1 << 15
|
||||
IFF_LOWER_UP = 1 << 16
|
||||
IFF_DORMANT = 1 << 17
|
||||
IFF_ECHO = 1 << 18
|
||||
)
|
||||
|
||||
// Interface link attributes, from uapi/linux/if_link.h.
|
||||
const (
|
||||
IFLA_UNSPEC = 0
|
||||
IFLA_ADDRESS = 1
|
||||
IFLA_BROADCAST = 2
|
||||
IFLA_IFNAME = 3
|
||||
IFLA_MTU = 4
|
||||
IFLA_LINK = 5
|
||||
IFLA_QDISC = 6
|
||||
IFLA_STATS = 7
|
||||
IFLA_COST = 8
|
||||
IFLA_PRIORITY = 9
|
||||
IFLA_MASTER = 10
|
||||
IFLA_WIRELESS = 11
|
||||
IFLA_PROTINFO = 12
|
||||
IFLA_TXQLEN = 13
|
||||
IFLA_MAP = 14
|
||||
IFLA_WEIGHT = 15
|
||||
IFLA_OPERSTATE = 16
|
||||
IFLA_LINKMODE = 17
|
||||
IFLA_LINKINFO = 18
|
||||
IFLA_NET_NS_PID = 19
|
||||
IFLA_IFALIAS = 20
|
||||
IFLA_NUM_VF = 21
|
||||
IFLA_VFINFO_LIST = 22
|
||||
IFLA_STATS64 = 23
|
||||
IFLA_VF_PORTS = 24
|
||||
IFLA_PORT_SELF = 25
|
||||
IFLA_AF_SPEC = 26
|
||||
IFLA_GROUP = 27
|
||||
IFLA_NET_NS_FD = 28
|
||||
IFLA_EXT_MASK = 29
|
||||
IFLA_PROMISCUITY = 30
|
||||
IFLA_NUM_TX_QUEUES = 31
|
||||
IFLA_NUM_RX_QUEUES = 32
|
||||
IFLA_CARRIER = 33
|
||||
IFLA_PHYS_PORT_ID = 34
|
||||
IFLA_CARRIER_CHANGES = 35
|
||||
IFLA_PHYS_SWITCH_ID = 36
|
||||
IFLA_LINK_NETNSID = 37
|
||||
IFLA_PHYS_PORT_NAME = 38
|
||||
IFLA_PROTO_DOWN = 39
|
||||
IFLA_GSO_MAX_SEGS = 40
|
||||
IFLA_GSO_MAX_SIZE = 41
|
||||
)
|
||||
|
||||
// Interface link info attributes, from uapi/linux/if_link.h.
|
||||
const (
|
||||
IFLA_INFO_UNSPEC = 0
|
||||
IFLA_INFO_KIND = 1
|
||||
IFLA_INFO_DATA = 2
|
||||
IFLA_INFO_XSTATS = 3
|
||||
IFLA_INFO_SLAVE_KIND = 4
|
||||
IFLA_INFO_SLAVE_DATA = 5
|
||||
)
|
||||
|
||||
// Virtuall ethernet attributes, from uapi/linux/veth.h.
|
||||
const (
|
||||
VETH_INFO_PEER = 1
|
||||
)
|
||||
|
||||
// InterfaceAddrMessage is struct ifaddrmsg, from uapi/linux/if_addr.h.
|
||||
//
|
||||
// +marshal
|
||||
type InterfaceAddrMessage struct {
|
||||
Family uint8
|
||||
PrefixLen uint8
|
||||
Flags uint8
|
||||
Scope uint8
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// InterfaceAddrMessageSize is the size of InterfaceAddrMessage.
|
||||
const InterfaceAddrMessageSize = 8
|
||||
|
||||
// Interface attributes, from uapi/linux/if_addr.h.
|
||||
const (
|
||||
IFA_UNSPEC = 0
|
||||
IFA_ADDRESS = 1
|
||||
IFA_LOCAL = 2
|
||||
IFA_LABEL = 3
|
||||
IFA_BROADCAST = 4
|
||||
IFA_ANYCAST = 5
|
||||
IFA_CACHEINFO = 6
|
||||
IFA_MULTICAST = 7
|
||||
IFA_FLAGS = 8
|
||||
)
|
||||
|
||||
// Device types, from uapi/linux/if_arp.h.
|
||||
const (
|
||||
ARPHRD_NONE = 65534
|
||||
ARPHRD_ETHER = 1
|
||||
ARPHRD_LOOPBACK = 772
|
||||
)
|
||||
|
||||
// RouteMessage is struct rtmsg, from uapi/linux/rtnetlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type RouteMessage struct {
|
||||
Family uint8
|
||||
DstLen uint8
|
||||
SrcLen uint8
|
||||
TOS uint8
|
||||
|
||||
Table uint8
|
||||
Protocol uint8
|
||||
Scope uint8
|
||||
Type uint8
|
||||
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
// SizeOfRouteMessage is the size of RouteMessage.
|
||||
const SizeOfRouteMessage = 12
|
||||
|
||||
// Route types, from uapi/linux/rtnetlink.h.
|
||||
const (
|
||||
// RTN_UNSPEC represents an unspecified route type.
|
||||
RTN_UNSPEC = 0
|
||||
|
||||
// RTN_UNICAST represents a unicast route.
|
||||
RTN_UNICAST = 1
|
||||
|
||||
// RTN_LOCAL represents a route that is accepted locally.
|
||||
RTN_LOCAL = 2
|
||||
|
||||
// RTN_BROADCAST represents a broadcast route (Traffic is accepted locally
|
||||
// as broadcast, and sent as broadcast).
|
||||
RTN_BROADCAST = 3
|
||||
|
||||
// RTN_ANYCAST represents a anycast route (Traffic is accepted locally as
|
||||
// broadcast but sent as unicast).
|
||||
RTN_ANYCAST = 6
|
||||
|
||||
// RTN_MULTICAST represents a multicast route.
|
||||
RTN_MULTICAST = 5
|
||||
|
||||
// RTN_BLACKHOLE represents a route where all traffic is dropped.
|
||||
RTN_BLACKHOLE = 6
|
||||
|
||||
// RTN_UNREACHABLE represents a route where the destination is unreachable.
|
||||
RTN_UNREACHABLE = 7
|
||||
|
||||
RTN_PROHIBIT = 8
|
||||
RTN_THROW = 9
|
||||
RTN_NAT = 10
|
||||
RTN_XRESOLVE = 11
|
||||
)
|
||||
|
||||
// Route protocols/origins, from uapi/linux/rtnetlink.h.
|
||||
const (
|
||||
RTPROT_UNSPEC = 0
|
||||
RTPROT_REDIRECT = 1
|
||||
RTPROT_KERNEL = 2
|
||||
RTPROT_BOOT = 3
|
||||
RTPROT_STATIC = 4
|
||||
RTPROT_GATED = 8
|
||||
RTPROT_RA = 9
|
||||
RTPROT_MRT = 10
|
||||
RTPROT_ZEBRA = 11
|
||||
RTPROT_BIRD = 12
|
||||
RTPROT_DNROUTED = 13
|
||||
RTPROT_XORP = 14
|
||||
RTPROT_NTK = 15
|
||||
RTPROT_DHCP = 16
|
||||
RTPROT_MROUTED = 17
|
||||
RTPROT_BABEL = 42
|
||||
RTPROT_BGP = 186
|
||||
RTPROT_ISIS = 187
|
||||
RTPROT_OSPF = 188
|
||||
RTPROT_RIP = 189
|
||||
RTPROT_EIGRP = 192
|
||||
)
|
||||
|
||||
// Route scopes, from uapi/linux/rtnetlink.h.
|
||||
const (
|
||||
RT_SCOPE_UNIVERSE = 0
|
||||
RT_SCOPE_SITE = 200
|
||||
RT_SCOPE_LINK = 253
|
||||
RT_SCOPE_HOST = 254
|
||||
RT_SCOPE_NOWHERE = 255
|
||||
)
|
||||
|
||||
// Route flags, from uapi/linux/rtnetlink.h.
|
||||
const (
|
||||
RTM_F_NOTIFY = 0x100
|
||||
RTM_F_CLONED = 0x200
|
||||
RTM_F_EQUALIZE = 0x400
|
||||
RTM_F_PREFIX = 0x800
|
||||
RTM_F_LOOKUP_TABLE = 0x1000
|
||||
RTM_F_FIB_MATCH = 0x2000
|
||||
)
|
||||
|
||||
// Route tables, from uapi/linux/rtnetlink.h.
|
||||
const (
|
||||
RT_TABLE_UNSPEC = 0
|
||||
RT_TABLE_COMPAT = 252
|
||||
RT_TABLE_DEFAULT = 253
|
||||
RT_TABLE_MAIN = 254
|
||||
RT_TABLE_LOCAL = 255
|
||||
)
|
||||
|
||||
// Route attributes, from uapi/linux/rtnetlink.h.
|
||||
const (
|
||||
RTA_UNSPEC = 0
|
||||
RTA_DST = 1
|
||||
RTA_SRC = 2
|
||||
RTA_IIF = 3
|
||||
RTA_OIF = 4
|
||||
RTA_GATEWAY = 5
|
||||
RTA_PRIORITY = 6
|
||||
RTA_PREFSRC = 7
|
||||
RTA_METRICS = 8
|
||||
RTA_MULTIPATH = 9
|
||||
RTA_PROTOINFO = 10
|
||||
RTA_FLOW = 11
|
||||
RTA_CACHEINFO = 12
|
||||
RTA_SESSION = 13
|
||||
RTA_MP_ALGO = 14
|
||||
RTA_TABLE = 15
|
||||
RTA_MARK = 16
|
||||
RTA_MFC_STATS = 17
|
||||
RTA_VIA = 18
|
||||
RTA_NEWDST = 19
|
||||
RTA_PREF = 20
|
||||
RTA_ENCAP_TYPE = 21
|
||||
RTA_ENCAP = 22
|
||||
RTA_EXPIRES = 23
|
||||
RTA_PAD = 24
|
||||
RTA_UID = 25
|
||||
RTA_TTL_PROPAGATE = 26
|
||||
RTA_IP_PROTO = 27
|
||||
RTA_SPORT = 28
|
||||
RTA_DPORT = 29
|
||||
)
|
||||
|
||||
// Route flags, from include/uapi/linux/route.h.
|
||||
const (
|
||||
RTF_GATEWAY = 0x2
|
||||
RTF_UP = 0x1
|
||||
)
|
||||
|
||||
// RtAttr is the header of optional addition route information, as a netlink
|
||||
// attribute. From include/uapi/linux/rtnetlink.h.
|
||||
//
|
||||
// +marshal
|
||||
type RtAttr struct {
|
||||
Len uint16
|
||||
Type uint16
|
||||
}
|
||||
|
||||
// SizeOfRtAttr is the size of RtAttr.
|
||||
const SizeOfRtAttr = 4
|
||||
464
pkg/abi/linux/nf_tables.go
Normal file
464
pkg/abi/linux/nf_tables.go
Normal file
|
|
@ -0,0 +1,464 @@
|
|||
// Copyright 2024 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// This file contains constants required to support nf_tables.
|
||||
|
||||
const NFT_MAX_HOOKS = NF_INET_NUMHOOKS + 1
|
||||
|
||||
// Name length constants for nf_table structures. These correspond to values in
|
||||
// include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_NAME_MAXLEN = 256
|
||||
NFT_TABLE_MAXNAMELEN = NFT_NAME_MAXLEN
|
||||
NFT_CHAIN_MAXNAMELEN = NFT_NAME_MAXLEN
|
||||
NFT_SET_MAXNAMELEN = NFT_NAME_MAXLEN
|
||||
NFT_OBJ_MAXNAMELEN = NFT_NAME_MAXLEN
|
||||
NFT_USERDATA_MAXLEN = 256
|
||||
NFT_OSF_MAXGENRELEN = 16
|
||||
)
|
||||
|
||||
// 16-byte Registers that can be used to maintain state for rules.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_REG_VERDICT = iota
|
||||
NFT_REG_1
|
||||
NFT_REG_2
|
||||
NFT_REG_3
|
||||
NFT_REG_4
|
||||
__NFT_REG_MAX
|
||||
)
|
||||
|
||||
// 4-byte Registers that can be used to maintain state for rules.
|
||||
// Note that these overlap with the 16-byte registers in memory.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_REG32_00 = 8 + iota
|
||||
NFT_REG32_01
|
||||
NFT_REG32_02
|
||||
NFT_REG32_03
|
||||
NFT_REG32_04
|
||||
NFT_REG32_05
|
||||
NFT_REG32_06
|
||||
NFT_REG32_07
|
||||
NFT_REG32_08
|
||||
NFT_REG32_09
|
||||
NFT_REG32_10
|
||||
NFT_REG32_11
|
||||
NFT_REG32_12
|
||||
NFT_REG32_13
|
||||
NFT_REG32_14
|
||||
NFT_REG32_15
|
||||
)
|
||||
|
||||
// Other register constants, corresponding to values in
|
||||
// include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_REG_MAX = __NFT_REG_MAX - 1 // Maximum register value
|
||||
NFT_REG_SIZE = 16 // Size of NFT_REG
|
||||
NFT_REG32_SIZE = 4 // Size of NFT_REG32
|
||||
NFT_REG32_COUNT = NFT_REG32_15 - NFT_REG32_00 + 1 // Count of 4-byte registers
|
||||
)
|
||||
|
||||
// Internal nf table verdicts. These are used for ruleset evaluation and
|
||||
// are not returned to userspace.
|
||||
//
|
||||
// These also share their numeric name space with the netfilter verdicts. When
|
||||
// used these values are converted to uint32 (purposefully overflowing the int).
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
// Continue evaluation of the current rule.
|
||||
NFT_CONTINUE int32 = -1
|
||||
|
||||
// Terminate evaluation of the current rule.
|
||||
NFT_BREAK int32 = -2
|
||||
|
||||
// Push the current chain on the jump stack and jump to a chain.
|
||||
NFT_JUMP int32 = -3
|
||||
|
||||
// Jump to a chain without pushing the current chain on the jump stack.
|
||||
NFT_GOTO int32 = -4
|
||||
|
||||
// Return to the topmost chain on the jump stack.
|
||||
NFT_RETURN int32 = -5
|
||||
)
|
||||
|
||||
// NfTableMsgType values map to operations within the nftables api.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
type NfTableMsgType uint16
|
||||
|
||||
// Netlink Netfilter table message types.
|
||||
const (
|
||||
NFT_MSG_NEWTABLE NfTableMsgType = iota
|
||||
NFT_MSG_GETTABLE
|
||||
NFT_MSG_DELTABLE
|
||||
NFT_MSG_NEWCHAIN
|
||||
NFT_MSG_GETCHAIN
|
||||
NFT_MSG_DELCHAIN
|
||||
NFT_MSG_NEWRULE
|
||||
NFT_MSG_GETRULE
|
||||
NFT_MSG_DELRULE
|
||||
NFT_MSG_NEWSET
|
||||
NFT_MSG_GETSET
|
||||
NFT_MSG_DELSET
|
||||
NFT_MSG_NEWSETELEM
|
||||
NFT_MSG_GETSETELEM
|
||||
NFT_MSG_DELSETELEM
|
||||
NFT_MSG_NEWGEN
|
||||
NFT_MSG_GETGEN
|
||||
NFT_MSG_TRACE
|
||||
NFT_MSG_NEWOBJ
|
||||
NFT_MSG_GETOBJ
|
||||
NFT_MSG_DELOBJ
|
||||
NFT_MSG_GETOBJ_RESET
|
||||
NFT_MSG_NEWFLOWTABLE
|
||||
NFT_MSG_GETFLOWTABLE
|
||||
NFT_MSG_DELFLOWTABLE
|
||||
NFT_MSG_GETRULE_RESET
|
||||
NFT_MSG_DESTROYTABLE
|
||||
NFT_MSG_DESTROYCHAIN
|
||||
NFT_MSG_DESTROYRULE
|
||||
NFT_MSG_DESTROYSET
|
||||
NFT_MSG_DESTROYSETELEM
|
||||
NFT_MSG_DESTROYOBJ
|
||||
NFT_MSG_DESTROYFLOWTABLE
|
||||
NFT_MSG_GETSETELEM_RESET
|
||||
NFT_MSG_MAX
|
||||
)
|
||||
|
||||
var nfTableMsgTypeStrings = [...]string{
|
||||
NFT_MSG_NEWTABLE: "NFT_MSG_NEWTABLE",
|
||||
NFT_MSG_GETTABLE: "NFT_MSG_GETTABLE",
|
||||
NFT_MSG_DELTABLE: "NFT_MSG_DELTABLE",
|
||||
NFT_MSG_NEWCHAIN: "NFT_MSG_NEWCHAIN",
|
||||
NFT_MSG_GETCHAIN: "NFT_MSG_GETCHAIN",
|
||||
NFT_MSG_DELCHAIN: "NFT_MSG_DELCHAIN",
|
||||
NFT_MSG_NEWRULE: "NFT_MSG_NEWRULE",
|
||||
NFT_MSG_GETRULE: "NFT_MSG_GETRULE",
|
||||
NFT_MSG_DELRULE: "NFT_MSG_DELRULE",
|
||||
NFT_MSG_NEWSET: "NFT_MSG_NEWSET",
|
||||
NFT_MSG_GETSET: "NFT_MSG_GETSET",
|
||||
NFT_MSG_DELSET: "NFT_MSG_DELSET",
|
||||
NFT_MSG_NEWSETELEM: "NFT_MSG_NEWSETELEM",
|
||||
NFT_MSG_GETSETELEM: "NFT_MSG_GETSETELEM",
|
||||
NFT_MSG_DELSETELEM: "NFT_MSG_DELSETELEM",
|
||||
NFT_MSG_NEWGEN: "NFT_MSG_NEWGEN",
|
||||
NFT_MSG_GETGEN: "NFT_MSG_GETGEN",
|
||||
NFT_MSG_TRACE: "NFT_MSG_TRACE",
|
||||
NFT_MSG_NEWOBJ: "NFT_MSG_NEWOBJ",
|
||||
NFT_MSG_GETOBJ: "NFT_MSG_GETOBJ",
|
||||
NFT_MSG_DELOBJ: "NFT_MSG_DELOBJ",
|
||||
NFT_MSG_GETOBJ_RESET: "NFT_MSG_GETOBJ_RESET",
|
||||
NFT_MSG_NEWFLOWTABLE: "NFT_MSG_NEWFLOWTABLE",
|
||||
NFT_MSG_GETFLOWTABLE: "NFT_MSG_GETFLOWTABLE",
|
||||
NFT_MSG_DELFLOWTABLE: "NFT_MSG_DELFLOWTABLE",
|
||||
NFT_MSG_GETRULE_RESET: "NFT_MSG_GETRULE_RESET",
|
||||
NFT_MSG_DESTROYTABLE: "NFT_MSG_DESTROYTABLE",
|
||||
NFT_MSG_DESTROYCHAIN: "NFT_MSG_DESTROYCHAIN",
|
||||
NFT_MSG_DESTROYRULE: "NFT_MSG_DESTROYRULE",
|
||||
NFT_MSG_DESTROYSET: "NFT_MSG_DESTROYSET",
|
||||
NFT_MSG_DESTROYSETELEM: "NFT_MSG_DESTROYSETELEM",
|
||||
NFT_MSG_DESTROYOBJ: "NFT_MSG_DESTROYOBJ",
|
||||
NFT_MSG_DESTROYFLOWTABLE: "NFT_MSG_DESTROYFLOWTABLE",
|
||||
NFT_MSG_GETSETELEM_RESET: "NFT_MSG_GETSETELEM_RESET",
|
||||
NFT_MSG_MAX: "NFT_MSG_MAX",
|
||||
}
|
||||
|
||||
// String returns the string representation of the NfTableMsgType.
|
||||
func (msg NfTableMsgType) String() string {
|
||||
if int(msg) < len(nfTableMsgTypeStrings) {
|
||||
return nfTableMsgTypeStrings[msg]
|
||||
}
|
||||
return "UNKNOWN"
|
||||
}
|
||||
|
||||
// NfTableListAttributes represents the netfilter attributes for lists of data.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFTA_LIST_UNSPEC uint16 = iota
|
||||
NFTA_LIST_ELEM
|
||||
__NFTA_LIST_MAX
|
||||
NFTA_LIST_MAX = __NFTA_LIST_MAX - 1
|
||||
)
|
||||
|
||||
// NfTableHookAttributes represents the netfilter hook attributes.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFTA_HOOK_UNSPEC uint16 = iota
|
||||
NFTA_HOOK_HOOKNUM
|
||||
NFTA_HOOK_PRIORITY
|
||||
NFTA_HOOK_DEV
|
||||
NFTA_HOOK_DEVS
|
||||
__NFTA_HOOK_MAX
|
||||
NFTA_HOOK_MAX = __NFTA_HOOK_MAX - 1
|
||||
)
|
||||
|
||||
// NfTableFlags represents table flags that can be set for a table, namely dormant.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_TABLE_F_DORMANT uint32 = 0x1
|
||||
NFT_TABLE_F_OWNER = 0x2
|
||||
NFT_TABLE_F_PERSIST = 0x4
|
||||
NFT_TABLE_F_MASK = NFT_TABLE_F_DORMANT | NFT_TABLE_F_OWNER | NFT_TABLE_F_PERSIST
|
||||
)
|
||||
|
||||
// NfTableAttributes represents the netfilter table attributes.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFTA_TABLE_UNSPEC uint16 = iota
|
||||
NFTA_TABLE_NAME
|
||||
NFTA_TABLE_FLAGS
|
||||
NFTA_TABLE_USE
|
||||
NFTA_TABLE_HANDLE
|
||||
NFTA_TABLE_PAD
|
||||
NFTA_TABLE_USERDATA
|
||||
NFTA_TABLE_OWNER
|
||||
__NFTA_TABLE_MAX
|
||||
)
|
||||
|
||||
// NFTA_TABLE_MAX is the maximum netfilter table attribute.
|
||||
const NFTA_TABLE_MAX = __NFTA_TABLE_MAX - 1
|
||||
|
||||
// NfTableChainFlags represents chain flags that can be set for a chain.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_CHAIN_BASE uint32 = (1 << 0)
|
||||
NFT_CHAIN_HW_OFFLOAD = (1 << 1)
|
||||
NFT_CHAIN_BINDING = (1 << 2)
|
||||
NFT_CHAIN_FLAGS = (NFT_CHAIN_BASE | NFT_CHAIN_HW_OFFLOAD | NFT_CHAIN_BINDING)
|
||||
)
|
||||
|
||||
// NfTableChainAttributes represents the netfilter chain attributes.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFTA_CHAIN_UNSPEC uint16 = iota
|
||||
NFTA_CHAIN_TABLE
|
||||
NFTA_CHAIN_HANDLE
|
||||
NFTA_CHAIN_NAME
|
||||
NFTA_CHAIN_HOOK
|
||||
NFTA_CHAIN_POLICY
|
||||
NFTA_CHAIN_USE
|
||||
NFTA_CHAIN_TYPE
|
||||
NFTA_CHAIN_COUNTERS
|
||||
NFTA_CHAIN_PAD
|
||||
NFTA_CHAIN_FLAGS
|
||||
NFTA_CHAIN_ID
|
||||
NFTA_CHAIN_USERDATA
|
||||
__NFTA_CHAIN_MAX
|
||||
NFTA_CHAIN_MAX = __NFTA_CHAIN_MAX - 1
|
||||
)
|
||||
|
||||
// NfTableRuleAttributes represents the netfilter rule attributes.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFTA_RULE_UNSPEC uint16 = iota
|
||||
NFTA_RULE_TABLE
|
||||
NFTA_RULE_CHAIN
|
||||
NFTA_RULE_HANDLE
|
||||
NFTA_RULE_EXPRESSIONS
|
||||
NFTA_RULE_COMPAT
|
||||
NFTA_RULE_POSITION
|
||||
NFTA_RULE_USERDATA
|
||||
NFTA_RULE_PAD
|
||||
NFTA_RULE_ID
|
||||
NFTA_RULE_POSITION_ID
|
||||
NFTA_RULE_CHAIN_ID
|
||||
__NFTA_RULE_MAX
|
||||
NFTA_RULE_MAX = __NFTA_RULE_MAX - 1
|
||||
)
|
||||
|
||||
// NfTableDataTypes represents the netfilter data types.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_DATA_VALUE = iota
|
||||
NFT_DATA_VERDICT = 0xffffff00
|
||||
)
|
||||
|
||||
// NfTableDataReservedMask represents the netfilter data reserved mask for internally used types.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_DATA_RESERVED_MASK = 0xffffff00
|
||||
)
|
||||
|
||||
// NfTableDataAttributes represents the netfilter data attributes.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFTA_DATA_UNSPEC uint16 = iota
|
||||
NFTA_DATA_VALUE
|
||||
NFTA_DATA_VERDICT
|
||||
__NFTA_DATA_MAX
|
||||
NFTA_DATA_MAX = __NFTA_DATA_MAX - 1
|
||||
)
|
||||
|
||||
// NFT_DATA_VALUE_MAXLEN is the maximum length of a netfilter data value.
|
||||
const NFT_DATA_VALUE_MAXLEN = 64
|
||||
|
||||
// NfTableVerdictAttributes represents the netfilter verdict attributes.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFTA_VERDICT_UNSPEC uint16 = iota
|
||||
NFTA_VERDICT_CODE
|
||||
NFTA_VERDICT_CHAIN
|
||||
NFTA_VERDICT_CHAIN_ID
|
||||
__NFTA_VERDICT_MAX
|
||||
NFTA_VERDICT_MAX = __NFTA_VERDICT_MAX - 1
|
||||
)
|
||||
|
||||
// NfTableExprAttributes represents the netfilter expression attributes.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFTA_EXPR_UNSPEC uint16 = iota
|
||||
NFTA_EXPR_NAME
|
||||
NFTA_EXPR_DATA
|
||||
__NFTA_EXPR_MAX
|
||||
NFTA_EXPR_MAX = __NFTA_EXPR_MAX - 1
|
||||
)
|
||||
|
||||
// NfTableImmediateAttributes represents the netfilter immediate attributes.
|
||||
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFTA_IMMEDIATE_UNSPEC uint16 = iota
|
||||
NFTA_IMMEDIATE_DREG
|
||||
NFTA_IMMEDIATE_DATA
|
||||
__NFTA_IMMEDIATE_MAX
|
||||
NFTA_IMMEDIATE_MAX = __NFTA_IMMEDIATE_MAX - 1
|
||||
)
|
||||
|
||||
// Nf table relational operators.
|
||||
// Used by the nft comparison operation to compare values in registers.
|
||||
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_CMP_EQ = iota // equal
|
||||
NFT_CMP_NEQ // not equal
|
||||
NFT_CMP_LT // less than
|
||||
NFT_CMP_LTE // less than or equal to
|
||||
NFT_CMP_GT // greater than
|
||||
NFT_CMP_GTE // greater than or equal to
|
||||
)
|
||||
|
||||
// Nf table range operators.
|
||||
// Used by the nft range operation to compare values in registers.
|
||||
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_RANGE_EQ = iota
|
||||
NFT_RANGE_NEQ
|
||||
)
|
||||
|
||||
// Nf table payload expression offset bases.
|
||||
// Used by the nft payload operations to access appropriate data in the packet.
|
||||
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_PAYLOAD_LL_HEADER = iota // link layer header
|
||||
NFT_PAYLOAD_NETWORK_HEADER // network header
|
||||
NFT_PAYLOAD_TRANSPORT_HEADER // transport header
|
||||
NFT_PAYLOAD_INNER_HEADER // inner header / payload
|
||||
NFT_PAYLOAD_TUN_HEADER // tunneling protocol header
|
||||
)
|
||||
|
||||
// Nf table payload expression checksum types.
|
||||
// Used by the nft payload set operation to mark the type of checksum to use.
|
||||
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_PAYLOAD_CSUM_NONE = iota // no checksumming
|
||||
NFT_PAYLOAD_CSUM_INET // internet checksum (RFC 791)
|
||||
NFT_PAYLOAD_CSUM_SCTP // CRC-32c, for use in SCTP header (RFC 3309)
|
||||
)
|
||||
|
||||
// Nf table payload expression checksum flags.
|
||||
// Used by the nft payload set operation to mark the flags for checksumming.
|
||||
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_PAYLOAD_L4CSUM_PSEUDOHDR = (1 << 0) // use pseudoheader for L4 checksum
|
||||
)
|
||||
|
||||
// Nf table bitwise operators.
|
||||
// Used by the nft bitwise operation to perform bitwise math over register data.
|
||||
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_BITWISE_BOOL = iota // mask-and-xor operation for NOT, AND, OR, & XOR
|
||||
NFT_BITWISE_LSHIFT // left-shift operation
|
||||
NFT_BITWISE_RSHIFT // right-shift operation
|
||||
)
|
||||
|
||||
// Nf table route expression keys.
|
||||
// Used by the nft route operation to determine the routing data to retrieve.
|
||||
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
// Traffic Class Identifier (Realm) associated with route
|
||||
NFT_RT_CLASSID = iota
|
||||
|
||||
// Routing nexthop for IPv4 (next IPv4 address to jump to)
|
||||
NFT_RT_NEXTHOP4
|
||||
|
||||
// Routing nexthop for IPv6 (next IPv6 address to jump to)
|
||||
NFT_RT_NEXTHOP6
|
||||
|
||||
// Maximum Segment Size for TCP connections (largest size for a single packet)
|
||||
NFT_RT_TCPMSS
|
||||
|
||||
// Bool for whether packet route involves a IPsec transform st xfrm is applied
|
||||
NFT_RT_XFRM
|
||||
)
|
||||
|
||||
// Nf table byteorder operators.
|
||||
// Used by the nft byteorder operation to convert data in a register to a
|
||||
// specific byte order.
|
||||
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_BYTEORDER_NTOH = iota // network to host operator
|
||||
NFT_BYTEORDER_HTON // host to network operator
|
||||
)
|
||||
|
||||
// Nf tables meta expression keys.
|
||||
// Used by the nft meta operation to retrieve meta data from the packet.
|
||||
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||
const (
|
||||
NFT_META_LEN = iota // Packet length
|
||||
NFT_META_PROTOCOL // Packet ethertype protocol, invalid in OUTPUT
|
||||
NFT_META_PRIORITY // Packet priority
|
||||
NFT_META_MARK // Packet mark
|
||||
NFT_META_IIF // Packet input interface index
|
||||
NFT_META_OIF // Packet output interface index
|
||||
NFT_META_IIFNAME // Packet input interface name
|
||||
NFT_META_OIFNAME // Packet output interface name
|
||||
NFT_META_IIFTYPE // Packet input interface type
|
||||
NFT_META_OIFTYPE // Packet output interface type
|
||||
NFT_META_SKUID // Originating socket UID
|
||||
NFT_META_SKGID // Originating socket GID
|
||||
NFT_META_NFTRACE // Packet nftrace bit
|
||||
NFT_META_RTCLASSID // Realm value of packet's route
|
||||
NFT_META_SECMARK // Packet secmark
|
||||
NFT_META_NFPROTO // Netfilter protocol
|
||||
NFT_META_L4PROTO // Layer 4 protocol number
|
||||
NFT_META_BRI_IIFNAME // Packet input bridge interface name
|
||||
NFT_META_BRI_OIFNAME // Packet output bridge interface name
|
||||
NFT_META_PKTTYPE // Packet type, special handling for loopback
|
||||
NFT_META_CPU // CPU id through smp_processor_id()
|
||||
NFT_META_IIFGROUP // Packet input interface group
|
||||
NFT_META_OIFGROUP // Packet output interface group
|
||||
NFT_META_CGROUP // Socket control group
|
||||
NFT_META_PRANDOM // A 32bit pseudo-random number
|
||||
NFT_META_SECPATH // Boolean, secpath_exists
|
||||
NFT_META_IIFKIND // Packet input interface kind name
|
||||
NFT_META_OIFKIND // Packet output interface kind name
|
||||
NFT_META_BRI_IIFPVID // Packet input bridge port pvid
|
||||
NFT_META_BRI_IIFVPROTO // Packet input bridge vlan proto
|
||||
NFT_META_TIME_NS // Time since epoch (in nanoseconds)
|
||||
NFT_META_TIME_DAY // Day of week (from 0 = Sunday to 6 = Saturday)
|
||||
NFT_META_TIME_HOUR // Hour of day (in sec), secs since start of day
|
||||
NFT_META_SDIF // Slave device interface index
|
||||
NFT_META_SDIFNAME // Slave device interface name
|
||||
NFT_META_BRI_BROUTE // Packet br_netfilter_broute bit
|
||||
)
|
||||
44
pkg/abi/linux/poll.go
Normal file
44
pkg/abi/linux/poll.go
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// PollFD is struct pollfd, used by poll(2)/ppoll(2), from uapi/asm-generic/poll.h.
|
||||
//
|
||||
// +marshal slice:PollFDSlice
|
||||
type PollFD struct {
|
||||
FD int32
|
||||
Events int16
|
||||
REvents int16
|
||||
}
|
||||
|
||||
// Poll event flags, used by poll(2)/ppoll(2) and/or
|
||||
// epoll_ctl(2)/epoll_wait(2), from uapi/asm-generic/poll.h.
|
||||
const (
|
||||
POLLIN = 0x0001
|
||||
POLLPRI = 0x0002
|
||||
POLLOUT = 0x0004
|
||||
POLLERR = 0x0008
|
||||
POLLHUP = 0x0010
|
||||
POLLNVAL = 0x0020
|
||||
POLLRDNORM = 0x0040
|
||||
POLLRDBAND = 0x0080
|
||||
POLLWRNORM = 0x0100
|
||||
POLLWRBAND = 0x0200
|
||||
POLLMSG = 0x0400
|
||||
POLLREMOVE = 0x1000
|
||||
POLLRDHUP = 0x2000
|
||||
POLLFREE = 0x4000
|
||||
POLL_BUSY_LOOP = 0x8000
|
||||
)
|
||||
179
pkg/abi/linux/prctl.go
Normal file
179
pkg/abi/linux/prctl.go
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// PR_* flags, from <linux/pcrtl.h> for prctl(2).
|
||||
const (
|
||||
// PR_SET_PDEATHSIG sets the process' death signal.
|
||||
PR_SET_PDEATHSIG = 1
|
||||
|
||||
// PR_GET_PDEATHSIG gets the process' death signal.
|
||||
PR_GET_PDEATHSIG = 2
|
||||
|
||||
// PR_GET_DUMPABLE gets the process' dumpable flag.
|
||||
PR_GET_DUMPABLE = 3
|
||||
|
||||
// PR_SET_DUMPABLE sets the process' dumpable flag.
|
||||
PR_SET_DUMPABLE = 4
|
||||
|
||||
// PR_GET_KEEPCAPS gets the value of the keep capabilities flag.
|
||||
PR_GET_KEEPCAPS = 7
|
||||
|
||||
// PR_SET_KEEPCAPS sets the value of the keep capabilities flag.
|
||||
PR_SET_KEEPCAPS = 8
|
||||
|
||||
// PR_GET_TIMING gets the process' timing method.
|
||||
PR_GET_TIMING = 13
|
||||
|
||||
// PR_SET_TIMING sets the process' timing method.
|
||||
PR_SET_TIMING = 14
|
||||
|
||||
// PR_SET_NAME sets the process' name.
|
||||
PR_SET_NAME = 15
|
||||
|
||||
// PR_GET_NAME gets the process' name.
|
||||
PR_GET_NAME = 16
|
||||
|
||||
// PR_GET_SECCOMP gets a process' seccomp mode.
|
||||
PR_GET_SECCOMP = 21
|
||||
|
||||
// PR_SET_SECCOMP sets a process' seccomp mode.
|
||||
PR_SET_SECCOMP = 22
|
||||
|
||||
// PR_CAPBSET_READ gets the capability bounding set.
|
||||
PR_CAPBSET_READ = 23
|
||||
|
||||
// PR_CAPBSET_DROP sets the capability bounding set.
|
||||
PR_CAPBSET_DROP = 24
|
||||
|
||||
// PR_GET_TSC gets the value of the flag determining whether the
|
||||
// timestamp counter can be read.
|
||||
PR_GET_TSC = 25
|
||||
|
||||
// PR_SET_TSC sets the value of the flag determining whether the
|
||||
// timestamp counter can be read.
|
||||
PR_SET_TSC = 26
|
||||
|
||||
// PR_SET_TIMERSLACK sets the process' time slack.
|
||||
PR_SET_TIMERSLACK = 29
|
||||
|
||||
// PR_GET_TIMERSLACK gets the process' time slack.
|
||||
PR_GET_TIMERSLACK = 30
|
||||
|
||||
// PR_TASK_PERF_EVENTS_DISABLE disables all performance counters
|
||||
// attached to the calling process.
|
||||
PR_TASK_PERF_EVENTS_DISABLE = 31
|
||||
|
||||
// PR_TASK_PERF_EVENTS_ENABLE enables all performance counters attached
|
||||
// to the calling process.
|
||||
PR_TASK_PERF_EVENTS_ENABLE = 32
|
||||
|
||||
// PR_MCE_KILL sets the machine check memory corruption kill policy for
|
||||
// the calling thread.
|
||||
PR_MCE_KILL = 33
|
||||
|
||||
// PR_MCE_KILL_GET gets the machine check memory corruption kill policy
|
||||
// for the calling thread.
|
||||
PR_MCE_KILL_GET = 34
|
||||
|
||||
// PR_SET_MM modifies certain kernel memory map descriptor fields of
|
||||
// the calling process. See prctl(2) for more information.
|
||||
PR_SET_MM = 35
|
||||
|
||||
PR_SET_MM_START_CODE = 1
|
||||
PR_SET_MM_END_CODE = 2
|
||||
PR_SET_MM_START_DATA = 3
|
||||
PR_SET_MM_END_DATA = 4
|
||||
PR_SET_MM_START_STACK = 5
|
||||
PR_SET_MM_START_BRK = 6
|
||||
PR_SET_MM_BRK = 7
|
||||
PR_SET_MM_ARG_START = 8
|
||||
PR_SET_MM_ARG_END = 9
|
||||
PR_SET_MM_ENV_START = 10
|
||||
PR_SET_MM_ENV_END = 11
|
||||
PR_SET_MM_AUXV = 12
|
||||
// PR_SET_MM_EXE_FILE supersedes the /proc/pid/exe symbolic link with a
|
||||
// new one pointing to a new executable file identified by the file
|
||||
// descriptor provided in arg3 argument. See prctl(2) for more
|
||||
// information.
|
||||
PR_SET_MM_EXE_FILE = 13
|
||||
PR_SET_MM_MAP = 14
|
||||
PR_SET_MM_MAP_SIZE = 15
|
||||
|
||||
// PR_SET_CHILD_SUBREAPER sets the "child subreaper" attribute of the
|
||||
// calling process.
|
||||
PR_SET_CHILD_SUBREAPER = 36
|
||||
|
||||
// PR_GET_CHILD_SUBREAPER gets the "child subreaper" attribute of the
|
||||
// calling process.
|
||||
PR_GET_CHILD_SUBREAPER = 37
|
||||
|
||||
// PR_SET_NO_NEW_PRIVS sets the calling thread's no_new_privs bit.
|
||||
PR_SET_NO_NEW_PRIVS = 38
|
||||
|
||||
// PR_GET_NO_NEW_PRIVS gets the calling thread's no_new_privs bit.
|
||||
PR_GET_NO_NEW_PRIVS = 39
|
||||
|
||||
// PR_GET_TID_ADDRESS retrieves the clear_child_tid address.
|
||||
PR_GET_TID_ADDRESS = 40
|
||||
|
||||
// PR_SET_THP_DISABLE sets the state of the "THP disable" flag for the
|
||||
// calling thread.
|
||||
PR_SET_THP_DISABLE = 41
|
||||
|
||||
// PR_GET_THP_DISABLE gets the state of the "THP disable" flag for the
|
||||
// calling thread.
|
||||
PR_GET_THP_DISABLE = 42
|
||||
|
||||
// PR_MPX_ENABLE_MANAGEMENT enables kernel management of Memory
|
||||
// Protection eXtensions (MPX) bounds tables.
|
||||
PR_MPX_ENABLE_MANAGEMENT = 43
|
||||
|
||||
// PR_MPX_DISABLE_MANAGEMENT disables kernel management of Memory
|
||||
// Protection eXtensions (MPX) bounds tables.
|
||||
PR_MPX_DISABLE_MANAGEMENT = 44
|
||||
|
||||
// The following constants are used to control thread scheduling on cores.
|
||||
PR_SCHED_CORE_SCOPE_THREAD = 0
|
||||
PR_SCHED_CORE_SCOPE_THREAD_GROUP = 1
|
||||
|
||||
// PR_SET_VMA sets VMA attributes.
|
||||
PR_SET_VMA = 0x53564d41
|
||||
PR_SET_VMA_ANON_NAME = 0
|
||||
// From kernel/sys.c:
|
||||
ANON_VMA_NAME_MAX_LEN = 80
|
||||
|
||||
// PR_SET_PTRACER allows a specific process (or any, if PR_SET_PTRACER_ANY is
|
||||
// specified) to ptrace the current task.
|
||||
PR_SET_PTRACER = 0x59616d61
|
||||
PR_SET_PTRACER_ANY = -1
|
||||
)
|
||||
|
||||
// From <asm/prctl.h>
|
||||
// Flags are used in syscall arch_prctl(2).
|
||||
const (
|
||||
ARCH_SET_GS = 0x1001
|
||||
ARCH_SET_FS = 0x1002
|
||||
ARCH_GET_FS = 0x1003
|
||||
ARCH_GET_GS = 0x1004
|
||||
ARCH_SET_CPUID = 0x1012
|
||||
)
|
||||
|
||||
// Flags for prctl(PR_SET_DUMPABLE), defined in include/linux/sched/coredump.h.
|
||||
const (
|
||||
SUID_DUMP_DISABLE = 0
|
||||
SUID_DUMP_USER = 1
|
||||
SUID_DUMP_ROOT = 2
|
||||
)
|
||||
95
pkg/abi/linux/ptrace.go
Normal file
95
pkg/abi/linux/ptrace.go
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// ptrace commands from include/uapi/linux/ptrace.h.
|
||||
const (
|
||||
PTRACE_TRACEME = 0
|
||||
PTRACE_PEEKTEXT = 1
|
||||
PTRACE_PEEKDATA = 2
|
||||
PTRACE_PEEKUSR = 3
|
||||
PTRACE_POKETEXT = 4
|
||||
PTRACE_POKEDATA = 5
|
||||
PTRACE_POKEUSR = 6
|
||||
PTRACE_CONT = 7
|
||||
PTRACE_KILL = 8
|
||||
PTRACE_SINGLESTEP = 9
|
||||
PTRACE_ATTACH = 16
|
||||
PTRACE_DETACH = 17
|
||||
PTRACE_SYSCALL = 24
|
||||
PTRACE_SETOPTIONS = 0x4200
|
||||
PTRACE_GETEVENTMSG = 0x4201
|
||||
PTRACE_GETSIGINFO = 0x4202
|
||||
PTRACE_SETSIGINFO = 0x4203
|
||||
PTRACE_GETREGSET = 0x4204
|
||||
PTRACE_SETREGSET = 0x4205
|
||||
PTRACE_SEIZE = 0x4206
|
||||
PTRACE_INTERRUPT = 0x4207
|
||||
PTRACE_LISTEN = 0x4208
|
||||
PTRACE_PEEKSIGINFO = 0x4209
|
||||
PTRACE_GETSIGMASK = 0x420a
|
||||
PTRACE_SETSIGMASK = 0x420b
|
||||
PTRACE_SECCOMP_GET_FILTER = 0x420c
|
||||
PTRACE_SECCOMP_GET_METADATA = 0x420d
|
||||
)
|
||||
|
||||
// ptrace commands from arch/x86/include/uapi/asm/ptrace-abi.h.
|
||||
const (
|
||||
PTRACE_GETREGS = 12
|
||||
PTRACE_SETREGS = 13
|
||||
PTRACE_GETFPREGS = 14
|
||||
PTRACE_SETFPREGS = 15
|
||||
PTRACE_GETFPXREGS = 18
|
||||
PTRACE_SETFPXREGS = 19
|
||||
PTRACE_OLDSETOPTIONS = 21
|
||||
PTRACE_GET_THREAD_AREA = 25
|
||||
PTRACE_SET_THREAD_AREA = 26
|
||||
PTRACE_ARCH_PRCTL = 30
|
||||
PTRACE_SYSEMU = 31
|
||||
PTRACE_SYSEMU_SINGLESTEP = 32
|
||||
PTRACE_SINGLEBLOCK = 33
|
||||
)
|
||||
|
||||
// ptrace event codes from include/uapi/linux/ptrace.h.
|
||||
const (
|
||||
PTRACE_EVENT_FORK = 1
|
||||
PTRACE_EVENT_VFORK = 2
|
||||
PTRACE_EVENT_CLONE = 3
|
||||
PTRACE_EVENT_EXEC = 4
|
||||
PTRACE_EVENT_VFORK_DONE = 5
|
||||
PTRACE_EVENT_EXIT = 6
|
||||
PTRACE_EVENT_SECCOMP = 7
|
||||
PTRACE_EVENT_STOP = 128
|
||||
)
|
||||
|
||||
// PTRACE_SETOPTIONS options from include/uapi/linux/ptrace.h.
|
||||
const (
|
||||
PTRACE_O_TRACESYSGOOD = 1
|
||||
PTRACE_O_TRACEFORK = 1 << PTRACE_EVENT_FORK
|
||||
PTRACE_O_TRACEVFORK = 1 << PTRACE_EVENT_VFORK
|
||||
PTRACE_O_TRACECLONE = 1 << PTRACE_EVENT_CLONE
|
||||
PTRACE_O_TRACEEXEC = 1 << PTRACE_EVENT_EXEC
|
||||
PTRACE_O_TRACEVFORKDONE = 1 << PTRACE_EVENT_VFORK_DONE
|
||||
PTRACE_O_TRACEEXIT = 1 << PTRACE_EVENT_EXIT
|
||||
PTRACE_O_TRACESECCOMP = 1 << PTRACE_EVENT_SECCOMP
|
||||
PTRACE_O_EXITKILL = 1 << 20
|
||||
PTRACE_O_SUSPEND_SECCOMP = 1 << 21
|
||||
)
|
||||
|
||||
// YAMA ptrace_scope levels from security/yama/yama_lsm.c.
|
||||
const (
|
||||
YAMA_SCOPE_DISABLED = 0
|
||||
YAMA_SCOPE_RELATIONAL = 1
|
||||
)
|
||||
69
pkg/abi/linux/ptrace_amd64.go
Normal file
69
pkg/abi/linux/ptrace_amd64.go
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build amd64
|
||||
// +build amd64
|
||||
|
||||
package linux
|
||||
|
||||
// PtraceRegs is the set of CPU registers exposed by ptrace. Source:
|
||||
// syscall.PtraceRegs.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type PtraceRegs struct {
|
||||
R15 uint64
|
||||
R14 uint64
|
||||
R13 uint64
|
||||
R12 uint64
|
||||
Rbp uint64
|
||||
Rbx uint64
|
||||
R11 uint64
|
||||
R10 uint64
|
||||
R9 uint64
|
||||
R8 uint64
|
||||
Rax uint64
|
||||
Rcx uint64
|
||||
Rdx uint64
|
||||
Rsi uint64
|
||||
Rdi uint64
|
||||
Orig_rax uint64
|
||||
Rip uint64
|
||||
Cs uint64
|
||||
Eflags uint64
|
||||
Rsp uint64
|
||||
Ss uint64
|
||||
Fs_base uint64
|
||||
Gs_base uint64
|
||||
Ds uint64
|
||||
Es uint64
|
||||
Fs uint64
|
||||
Gs uint64
|
||||
}
|
||||
|
||||
// InstructionPointer returns the address of the next instruction to
|
||||
// be executed.
|
||||
func (p *PtraceRegs) InstructionPointer() uint64 {
|
||||
return p.Rip
|
||||
}
|
||||
|
||||
// StackPointer returns the address of the Stack pointer.
|
||||
func (p *PtraceRegs) StackPointer() uint64 {
|
||||
return p.Rsp
|
||||
}
|
||||
|
||||
// SetStackPointer sets the stack pointer to the specified value.
|
||||
func (p *PtraceRegs) SetStackPointer(sp uint64) {
|
||||
p.Rsp = sp
|
||||
}
|
||||
77
pkg/abi/linux/ptrace_arm64.go
Normal file
77
pkg/abi/linux/ptrace_arm64.go
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build arm64
|
||||
// +build arm64
|
||||
|
||||
package linux
|
||||
|
||||
const (
|
||||
// PSR bits
|
||||
PSR_MODE_EL0t = 0x00000000
|
||||
PSR_MODE_EL1t = 0x00000004
|
||||
PSR_MODE_EL1h = 0x00000005
|
||||
PSR_MODE_EL2t = 0x00000008
|
||||
PSR_MODE_EL2h = 0x00000009
|
||||
PSR_MODE_EL3t = 0x0000000c
|
||||
PSR_MODE_EL3h = 0x0000000d
|
||||
PSR_MODE_MASK = 0x0000000f
|
||||
|
||||
// AArch32 CPSR bits
|
||||
PSR_MODE32_BIT = 0x00000010
|
||||
|
||||
// AArch64 SPSR bits
|
||||
PSR_F_BIT = 0x00000040
|
||||
PSR_I_BIT = 0x00000080
|
||||
PSR_A_BIT = 0x00000100
|
||||
PSR_D_BIT = 0x00000200
|
||||
PSR_BTYPE_MASK = 0x00000c00
|
||||
PSR_SSBS_BIT = 0x00001000
|
||||
PSR_PAN_BIT = 0x00400000
|
||||
PSR_UAO_BIT = 0x00800000
|
||||
PSR_DIT_BIT = 0x01000000
|
||||
PSR_TCO_BIT = 0x02000000
|
||||
PSR_V_BIT = 0x10000000
|
||||
PSR_C_BIT = 0x20000000
|
||||
PSR_Z_BIT = 0x40000000
|
||||
PSR_N_BIT = 0x80000000
|
||||
)
|
||||
|
||||
// PtraceRegs is the set of CPU registers exposed by ptrace. Source:
|
||||
// syscall.PtraceRegs.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type PtraceRegs struct {
|
||||
Regs [31]uint64
|
||||
Sp uint64
|
||||
Pc uint64
|
||||
Pstate uint64
|
||||
}
|
||||
|
||||
// InstructionPointer returns the address of the next instruction to be
|
||||
// executed.
|
||||
func (p *PtraceRegs) InstructionPointer() uint64 {
|
||||
return p.Pc
|
||||
}
|
||||
|
||||
// StackPointer returns the address of the Stack pointer.
|
||||
func (p *PtraceRegs) StackPointer() uint64 {
|
||||
return p.Sp
|
||||
}
|
||||
|
||||
// SetStackPointer sets the stack pointer to the specified value.
|
||||
func (p *PtraceRegs) SetStackPointer(sp uint64) {
|
||||
p.Sp = sp
|
||||
}
|
||||
130
pkg/abi/linux/rseq.go
Normal file
130
pkg/abi/linux/rseq.go
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Flags passed to rseq(2).
|
||||
//
|
||||
// Defined in include/uapi/linux/rseq.h.
|
||||
const (
|
||||
// RSEQ_FLAG_UNREGISTER unregisters the current thread.
|
||||
RSEQ_FLAG_UNREGISTER = 1 << 0
|
||||
)
|
||||
|
||||
// Critical section flags used in RSeqCriticalSection.Flags and RSeq.Flags.
|
||||
//
|
||||
// Defined in include/uapi/linux/rseq.h.
|
||||
const (
|
||||
// RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT inhibits restart on preemption.
|
||||
RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = 1 << 0
|
||||
|
||||
// RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL inhibits restart on signal
|
||||
// delivery.
|
||||
RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = 1 << 1
|
||||
|
||||
// RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE inhibits restart on CPU
|
||||
// migration.
|
||||
RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = 1 << 2
|
||||
)
|
||||
|
||||
// RSeqCriticalSection describes a restartable sequences critical section. It
|
||||
// is equivalent to struct rseq_cs, defined in include/uapi/linux/rseq.h.
|
||||
//
|
||||
// In userspace, this structure is always aligned to 32 bytes.
|
||||
//
|
||||
// +marshal
|
||||
type RSeqCriticalSection struct {
|
||||
// Version is the version of this structure. Version 0 is defined here.
|
||||
Version uint32
|
||||
|
||||
// Flags are the critical section flags, defined above.
|
||||
Flags uint32
|
||||
|
||||
// Start is the start address of the critical section.
|
||||
Start uint64
|
||||
|
||||
// PostCommitOffset is the offset from Start of the first instruction
|
||||
// outside of the critical section.
|
||||
PostCommitOffset uint64
|
||||
|
||||
// Abort is the abort address. It must be outside the critical section,
|
||||
// and the 4 bytes prior must match the abort signature.
|
||||
Abort uint64
|
||||
}
|
||||
|
||||
const (
|
||||
// SizeOfRSeqCriticalSection is the size of RSeqCriticalSection.
|
||||
SizeOfRSeqCriticalSection = 32
|
||||
|
||||
// SizeOfRSeqSignature is the size of the signature immediately
|
||||
// preceding RSeqCriticalSection.Abort.
|
||||
SizeOfRSeqSignature = 4
|
||||
)
|
||||
|
||||
// Special values for RSeq.CPUID, defined in include/uapi/linux/rseq.h.
|
||||
const (
|
||||
// RSEQ_CPU_ID_UNINITIALIZED indicates that this thread has not
|
||||
// performed rseq initialization.
|
||||
RSEQ_CPU_ID_UNINITIALIZED = ^uint32(0) // -1
|
||||
|
||||
// RSEQ_CPU_ID_REGISTRATION_FAILED indicates that rseq initialization
|
||||
// failed.
|
||||
RSEQ_CPU_ID_REGISTRATION_FAILED = ^uint32(1) // -2
|
||||
)
|
||||
|
||||
// RSeq is the thread-local restartable sequences config/status. It
|
||||
// is equivalent to struct rseq, defined in include/uapi/linux/rseq.h.
|
||||
//
|
||||
// In userspace, this structure is always aligned to 32 bytes.
|
||||
type RSeq struct {
|
||||
// CPUIDStart contains the current CPU ID if rseq is initialized.
|
||||
//
|
||||
// This field should only be read by the thread which registered this
|
||||
// structure, and must be read atomically.
|
||||
CPUIDStart uint32
|
||||
|
||||
// CPUID contains the current CPU ID or one of the CPU ID special
|
||||
// values defined above.
|
||||
//
|
||||
// This field should only be read by the thread which registered this
|
||||
// structure, and must be read atomically.
|
||||
CPUID uint32
|
||||
|
||||
// RSeqCriticalSection is a pointer to the current RSeqCriticalSection
|
||||
// block, or NULL. It is reset to NULL by the kernel on restart or
|
||||
// non-restarting preempt/signal.
|
||||
//
|
||||
// This field should only be written by the thread which registered
|
||||
// this structure, and must be written atomically.
|
||||
RSeqCriticalSection uint64
|
||||
|
||||
// Flags are the critical section flags that apply to all critical
|
||||
// sections on this thread, defined above.
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
const (
|
||||
// SizeOfRSeq is the size of RSeq.
|
||||
//
|
||||
// Note that RSeq is naively 24 bytes. However, it has 32-byte
|
||||
// alignment, which in C increases sizeof to 32. That is the size that
|
||||
// the Linux kernel uses.
|
||||
SizeOfRSeq = 32
|
||||
|
||||
// AlignOfRSeq is the standard alignment of RSeq.
|
||||
AlignOfRSeq = 32
|
||||
|
||||
// OffsetOfRSeqCriticalSection is the offset of RSeqCriticalSection in RSeq.
|
||||
OffsetOfRSeqCriticalSection = 8
|
||||
)
|
||||
48
pkg/abi/linux/rusage.go
Normal file
48
pkg/abi/linux/rusage.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Flags that may be used with wait4(2) and getrusage(2).
|
||||
const (
|
||||
// wait4(2) uses this to aggregate RUSAGE_SELF and RUSAGE_CHILDREN.
|
||||
RUSAGE_BOTH = -0x2
|
||||
|
||||
// getrusage(2) flags.
|
||||
RUSAGE_CHILDREN = -0x1
|
||||
RUSAGE_SELF = 0x0
|
||||
RUSAGE_THREAD = 0x1
|
||||
)
|
||||
|
||||
// Rusage represents the Linux struct rusage.
|
||||
//
|
||||
// +marshal
|
||||
type Rusage struct {
|
||||
UTime Timeval
|
||||
STime Timeval
|
||||
MaxRSS int64
|
||||
IXRSS int64
|
||||
IDRSS int64
|
||||
ISRSS int64
|
||||
MinFlt int64
|
||||
MajFlt int64
|
||||
NSwap int64
|
||||
InBlock int64
|
||||
OuBlock int64
|
||||
MsgSnd int64
|
||||
MsgRcv int64
|
||||
NSignals int64
|
||||
NVCSw int64
|
||||
NIvCSw int64
|
||||
}
|
||||
37
pkg/abi/linux/sched.go
Normal file
37
pkg/abi/linux/sched.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Scheduling policies, exposed by sched_getscheduler(2)/sched_setscheduler(2).
|
||||
const (
|
||||
SCHED_NORMAL = 0
|
||||
SCHED_FIFO = 1
|
||||
SCHED_RR = 2
|
||||
SCHED_BATCH = 3
|
||||
SCHED_IDLE = 5
|
||||
SCHED_DEADLINE = 6
|
||||
SCHED_MICROQ = 16
|
||||
|
||||
// SCHED_RESET_ON_FORK is a flag that indicates that the process is
|
||||
// reverted back to SCHED_NORMAL on fork.
|
||||
SCHED_RESET_ON_FORK = 0x40000000
|
||||
)
|
||||
|
||||
// Scheduling priority group selectors.
|
||||
const (
|
||||
PRIO_PGRP = 0x1
|
||||
PRIO_PROCESS = 0x0
|
||||
PRIO_USER = 0x2
|
||||
)
|
||||
173
pkg/abi/linux/seccomp.go
Normal file
173
pkg/abi/linux/seccomp.go
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Seccomp constants taken from <linux/seccomp.h>.
|
||||
const (
|
||||
SECCOMP_MODE_NONE = 0
|
||||
SECCOMP_MODE_FILTER = 2
|
||||
|
||||
SECCOMP_RET_ACTION_FULL = 0xffff0000
|
||||
SECCOMP_RET_ACTION = 0x7fff0000
|
||||
SECCOMP_RET_DATA = 0x0000ffff
|
||||
|
||||
SECCOMP_SET_MODE_FILTER = 1
|
||||
SECCOMP_GET_ACTION_AVAIL = 2
|
||||
SECCOMP_GET_NOTIF_SIZES = 3
|
||||
|
||||
SECCOMP_FILTER_FLAG_TSYNC = 1
|
||||
SECCOMP_FILTER_FLAG_NEW_LISTENER = 1 << 3
|
||||
|
||||
SECCOMP_USER_NOTIF_FLAG_CONTINUE = 1
|
||||
|
||||
SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100
|
||||
SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||
|
||||
SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 1
|
||||
)
|
||||
|
||||
// BPFAction is an action for a BPF filter.
|
||||
type BPFAction uint32
|
||||
|
||||
// BPFAction definitions.
|
||||
const (
|
||||
SECCOMP_RET_KILL_PROCESS BPFAction = 0x80000000
|
||||
SECCOMP_RET_KILL_THREAD BPFAction = 0x00000000
|
||||
SECCOMP_RET_TRAP BPFAction = 0x00030000
|
||||
SECCOMP_RET_ERRNO BPFAction = 0x00050000
|
||||
SECCOMP_RET_TRACE BPFAction = 0x7ff00000
|
||||
SECCOMP_RET_USER_NOTIF BPFAction = 0x7fc00000
|
||||
SECCOMP_RET_ALLOW BPFAction = 0x7fff0000
|
||||
)
|
||||
|
||||
func (a BPFAction) String() string {
|
||||
switch a & SECCOMP_RET_ACTION_FULL {
|
||||
case SECCOMP_RET_KILL_PROCESS:
|
||||
return "kill process"
|
||||
case SECCOMP_RET_KILL_THREAD:
|
||||
return "kill thread"
|
||||
case SECCOMP_RET_TRAP:
|
||||
data := a.Data()
|
||||
if data == 0 {
|
||||
return "trap"
|
||||
}
|
||||
return fmt.Sprintf("trap (data=%#x)", data)
|
||||
case SECCOMP_RET_ERRNO:
|
||||
return fmt.Sprintf("return errno=%#x", a.Data())
|
||||
case SECCOMP_RET_TRACE:
|
||||
data := a.Data()
|
||||
if data == 0 {
|
||||
return "trace"
|
||||
}
|
||||
return fmt.Sprintf("trace (data=%#x)", data)
|
||||
case SECCOMP_RET_ALLOW:
|
||||
return "allow"
|
||||
case SECCOMP_RET_USER_NOTIF:
|
||||
return "unotify"
|
||||
}
|
||||
return fmt.Sprintf("invalid action: %#x", uint32(a))
|
||||
}
|
||||
|
||||
// Data returns the SECCOMP_RET_DATA portion of the action.
|
||||
func (a BPFAction) Data() uint16 {
|
||||
return uint16(a & SECCOMP_RET_DATA)
|
||||
}
|
||||
|
||||
// WithReturnCode sets the lower 16 bits of the SECCOMP_RET_ERRNO or
|
||||
// SECCOMP_RET_TRACE actions to the provided return code, overwriting the previous
|
||||
// action, and returns a new BPFAction. If not SECCOMP_RET_ERRNO or
|
||||
// SECCOMP_RET_TRACE then this panics.
|
||||
func (a BPFAction) WithReturnCode(code uint16) BPFAction {
|
||||
// mask out the previous return value
|
||||
baseAction := a & SECCOMP_RET_ACTION_FULL
|
||||
if baseAction == SECCOMP_RET_ERRNO || baseAction == SECCOMP_RET_TRACE {
|
||||
return BPFAction(uint32(baseAction) | uint32(code))
|
||||
}
|
||||
panic("WithReturnCode only valid for SECCOMP_RET_ERRNO and SECCOMP_RET_TRACE")
|
||||
}
|
||||
|
||||
// SockFprog is sock_fprog taken from <linux/filter.h>.
|
||||
type SockFprog struct {
|
||||
Len uint16
|
||||
pad [6]byte
|
||||
Filter *BPFInstruction
|
||||
}
|
||||
|
||||
// SeccompData is equivalent to struct seccomp_data, which contains the data
|
||||
// passed to seccomp-bpf filters.
|
||||
//
|
||||
// +marshal
|
||||
type SeccompData struct {
|
||||
// Nr is the system call number.
|
||||
Nr int32
|
||||
|
||||
// Arch is an AUDIT_ARCH_* value indicating the system call convention.
|
||||
Arch uint32
|
||||
|
||||
// InstructionPointer is the value of the instruction pointer at the time
|
||||
// of the system call.
|
||||
InstructionPointer uint64
|
||||
|
||||
// Args contains the first 6 system call arguments.
|
||||
Args [6]uint64
|
||||
}
|
||||
|
||||
// SeccompNotifResp is equivalent to struct seccomp_notif_resp.
|
||||
//
|
||||
// +marshal
|
||||
type SeccompNotifResp struct {
|
||||
ID uint64
|
||||
Val int64
|
||||
Error int32
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
// SeccompNotifSizes is equivalent to struct seccomp_notif_sizes.
|
||||
//
|
||||
// +marshal
|
||||
type SeccompNotifSizes struct {
|
||||
Notif uint16
|
||||
Notif_resp uint16
|
||||
Data uint16
|
||||
}
|
||||
|
||||
// SeccompNotif is equivalent to struct seccomp_notif.
|
||||
//
|
||||
// +marshal
|
||||
type SeccompNotif struct {
|
||||
ID uint64
|
||||
Pid int32
|
||||
Flags uint32
|
||||
Data SeccompData
|
||||
}
|
||||
|
||||
// String returns a human-friendly representation of this `SeccompData`.
|
||||
func (sd SeccompData) String() string {
|
||||
return fmt.Sprintf(
|
||||
"sysno=%d arch=%#x rip=%#x args=[%#x %#x %#x %#x %#x %#x]",
|
||||
sd.Nr,
|
||||
sd.Arch,
|
||||
sd.InstructionPointer,
|
||||
sd.Args[0],
|
||||
sd.Args[1],
|
||||
sd.Args[2],
|
||||
sd.Args[3],
|
||||
sd.Args[4],
|
||||
sd.Args[5],
|
||||
)
|
||||
}
|
||||
82
pkg/abi/linux/sem.go
Normal file
82
pkg/abi/linux/sem.go
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// semctl Command Definitions. Source: include/uapi/linux/sem.h
|
||||
const (
|
||||
GETPID = 11
|
||||
GETVAL = 12
|
||||
GETALL = 13
|
||||
GETNCNT = 14
|
||||
GETZCNT = 15
|
||||
SETVAL = 16
|
||||
SETALL = 17
|
||||
)
|
||||
|
||||
// ipcs ctl cmds. Source: include/uapi/linux/sem.h
|
||||
const (
|
||||
SEM_STAT = 18
|
||||
SEM_INFO = 19
|
||||
SEM_STAT_ANY = 20
|
||||
)
|
||||
|
||||
// Information about system-wide semaphore limits and parameters.
|
||||
//
|
||||
// Source: include/uapi/linux/sem.h
|
||||
const (
|
||||
SEMMNI = 32000
|
||||
SEMMSL = 32000
|
||||
SEMMNS = SEMMNI * SEMMSL
|
||||
SEMOPM = 500
|
||||
SEMVMX = 32767
|
||||
SEMAEM = SEMVMX
|
||||
|
||||
SEMUME = SEMOPM
|
||||
SEMMNU = SEMMNS
|
||||
SEMMAP = SEMMNS
|
||||
SEMUSZ = 20
|
||||
)
|
||||
|
||||
// Semaphore flags.
|
||||
const (
|
||||
SEM_UNDO = 0x1000
|
||||
)
|
||||
|
||||
// Sembuf is equivalent to struct sembuf.
|
||||
//
|
||||
// +marshal slice:SembufSlice
|
||||
type Sembuf struct {
|
||||
SemNum uint16
|
||||
SemOp int16
|
||||
SemFlg int16
|
||||
}
|
||||
|
||||
// SemInfo is equivalent to struct seminfo.
|
||||
//
|
||||
// Source: include/uapi/linux/sem.h
|
||||
//
|
||||
// +marshal
|
||||
type SemInfo struct {
|
||||
SemMap uint32
|
||||
SemMni uint32
|
||||
SemMns uint32
|
||||
SemMnu uint32
|
||||
SemMsl uint32
|
||||
SemOpm uint32
|
||||
SemUme uint32
|
||||
SemUsz uint32
|
||||
SemVmx uint32
|
||||
SemAem uint32
|
||||
}
|
||||
34
pkg/abi/linux/sem_amd64.go
Normal file
34
pkg/abi/linux/sem_amd64.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build amd64
|
||||
// +build amd64
|
||||
|
||||
package linux
|
||||
|
||||
// SemidDS is equivalent to struct semid64_ds.
|
||||
//
|
||||
// Source: arch/x86/include/uapi/asm/sembuf.h
|
||||
//
|
||||
// +marshal
|
||||
type SemidDS struct {
|
||||
SemPerm IPCPerm
|
||||
SemOTime TimeT
|
||||
unused1 uint64
|
||||
SemCTime TimeT
|
||||
unused2 uint64
|
||||
SemNSems uint64
|
||||
unused3 uint64
|
||||
unused4 uint64
|
||||
}
|
||||
32
pkg/abi/linux/sem_arm64.go
Normal file
32
pkg/abi/linux/sem_arm64.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build arm64
|
||||
// +build arm64
|
||||
|
||||
package linux
|
||||
|
||||
// SemidDS is equivalent to struct semid64_ds.
|
||||
//
|
||||
// Source: include/uapi/asm-generic/sembuf.h
|
||||
//
|
||||
// +marshal
|
||||
type SemidDS struct {
|
||||
SemPerm IPCPerm
|
||||
SemOTime TimeT
|
||||
SemCTime TimeT
|
||||
SemNSems uint64
|
||||
unused3 uint64
|
||||
unused4 uint64
|
||||
}
|
||||
92
pkg/abi/linux/shm.go
Normal file
92
pkg/abi/linux/shm.go
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import "math"
|
||||
|
||||
// shmat(2) flags. Source: include/uapi/linux/shm.h
|
||||
const (
|
||||
SHM_RDONLY = 0o10000 // Read-only access.
|
||||
SHM_RND = 0o20000 // Round attach address to SHMLBA boundary.
|
||||
SHM_REMAP = 0o40000 // Take-over region on attach.
|
||||
SHM_EXEC = 0o100000 // Execution access.
|
||||
)
|
||||
|
||||
// IPCPerm.Mode upper byte flags. Source: include/linux/shm.h
|
||||
const (
|
||||
SHM_DEST = 0o1000 // Segment will be destroyed on last detach.
|
||||
SHM_LOCKED = 0o2000 // Segment will not be swapped.
|
||||
SHM_HUGETLB = 0o4000 // Segment will use huge TLB pages.
|
||||
SHM_NORESERVE = 0o10000 // Don't check for reservations.
|
||||
)
|
||||
|
||||
// Additional Linux-only flags for shmctl(2). Source: include/uapi/linux/shm.h
|
||||
const (
|
||||
SHM_LOCK = 11
|
||||
SHM_UNLOCK = 12
|
||||
SHM_STAT = 13
|
||||
SHM_INFO = 14
|
||||
)
|
||||
|
||||
// SHM defaults as specified by linux. Source: include/uapi/linux/shm.h
|
||||
const (
|
||||
SHMMIN = 1
|
||||
SHMMNI = 4096
|
||||
SHMMAX = math.MaxUint64 - 1<<24
|
||||
SHMALL = math.MaxUint64 - 1<<24
|
||||
SHMSEG = 4096
|
||||
)
|
||||
|
||||
// ShmidDS is equivalent to struct shmid64_ds. Source:
|
||||
// include/uapi/asm-generic/shmbuf.h
|
||||
//
|
||||
// +marshal
|
||||
type ShmidDS struct {
|
||||
ShmPerm IPCPerm
|
||||
ShmSegsz uint64
|
||||
ShmAtime TimeT
|
||||
ShmDtime TimeT
|
||||
ShmCtime TimeT
|
||||
ShmCpid int32
|
||||
ShmLpid int32
|
||||
ShmNattach uint64
|
||||
|
||||
Unused4 uint64
|
||||
Unused5 uint64
|
||||
}
|
||||
|
||||
// ShmParams is equivalent to struct shminfo. Source: include/uapi/linux/shm.h
|
||||
//
|
||||
// +marshal
|
||||
type ShmParams struct {
|
||||
ShmMax uint64
|
||||
ShmMin uint64
|
||||
ShmMni uint64
|
||||
ShmSeg uint64
|
||||
ShmAll uint64
|
||||
}
|
||||
|
||||
// ShmInfo is equivalent to struct shm_info. Source: include/uapi/linux/shm.h
|
||||
//
|
||||
// +marshal
|
||||
type ShmInfo struct {
|
||||
UsedIDs int32 // Number of currently existing segments.
|
||||
_ [4]byte
|
||||
ShmTot uint64 // Total number of shared memory pages.
|
||||
ShmRss uint64 // Number of resident shared memory pages.
|
||||
ShmSwp uint64 // Number of swapped shared memory pages.
|
||||
SwapAttempts uint64 // Unused since Linux 2.4.
|
||||
SwapSuccesses uint64 // Unused since Linux 2.4.
|
||||
}
|
||||
552
pkg/abi/linux/signal.go
Normal file
552
pkg/abi/linux/signal.go
Normal file
|
|
@ -0,0 +1,552 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"github.com/sagernet/gvisor/pkg/bits"
|
||||
"github.com/sagernet/gvisor/pkg/hostarch"
|
||||
)
|
||||
|
||||
const (
|
||||
// SignalMaximum is the highest valid signal number.
|
||||
SignalMaximum = 64
|
||||
|
||||
// FirstStdSignal is the lowest standard signal number.
|
||||
FirstStdSignal = 1
|
||||
|
||||
// LastStdSignal is the highest standard signal number.
|
||||
LastStdSignal = 31
|
||||
|
||||
// FirstRTSignal is the lowest real-time signal number.
|
||||
//
|
||||
// 32 (SIGCANCEL) and 33 (SIGSETXID) are used internally by glibc.
|
||||
FirstRTSignal = 32
|
||||
|
||||
// LastRTSignal is the highest real-time signal number.
|
||||
LastRTSignal = 64
|
||||
|
||||
// NumStdSignals is the number of standard signals.
|
||||
NumStdSignals = LastStdSignal - FirstStdSignal + 1
|
||||
|
||||
// NumRTSignals is the number of realtime signals.
|
||||
NumRTSignals = LastRTSignal - FirstRTSignal + 1
|
||||
)
|
||||
|
||||
// Signal is a signal number.
|
||||
type Signal int
|
||||
|
||||
// IsValid returns true if s is a valid standard or realtime signal. (0 is not
|
||||
// considered valid; interfaces special-casing signal number 0 should check for
|
||||
// 0 first before asserting validity.)
|
||||
func (s Signal) IsValid() bool {
|
||||
return s > 0 && s <= SignalMaximum
|
||||
}
|
||||
|
||||
// IsStandard returns true if s is a standard signal.
|
||||
//
|
||||
// Preconditions: s.IsValid().
|
||||
func (s Signal) IsStandard() bool {
|
||||
return s <= LastStdSignal
|
||||
}
|
||||
|
||||
// IsRealtime returns true if s is a realtime signal.
|
||||
//
|
||||
// Preconditions: s.IsValid().
|
||||
func (s Signal) IsRealtime() bool {
|
||||
return s >= FirstRTSignal
|
||||
}
|
||||
|
||||
// Index returns the index for signal s into arrays of both standard and
|
||||
// realtime signals (e.g. signal masks).
|
||||
//
|
||||
// Preconditions: s.IsValid().
|
||||
func (s Signal) Index() int {
|
||||
return int(s - 1)
|
||||
}
|
||||
|
||||
// Signals.
|
||||
const (
|
||||
SIGABRT = Signal(6)
|
||||
SIGALRM = Signal(14)
|
||||
SIGBUS = Signal(7)
|
||||
SIGCHLD = Signal(17)
|
||||
SIGCLD = Signal(17)
|
||||
SIGCONT = Signal(18)
|
||||
SIGFPE = Signal(8)
|
||||
SIGHUP = Signal(1)
|
||||
SIGILL = Signal(4)
|
||||
SIGINT = Signal(2)
|
||||
SIGIO = Signal(29)
|
||||
SIGIOT = Signal(6)
|
||||
SIGKILL = Signal(9)
|
||||
SIGPIPE = Signal(13)
|
||||
SIGPOLL = Signal(29)
|
||||
SIGPROF = Signal(27)
|
||||
SIGPWR = Signal(30)
|
||||
SIGQUIT = Signal(3)
|
||||
SIGSEGV = Signal(11)
|
||||
SIGSTKFLT = Signal(16)
|
||||
SIGSTOP = Signal(19)
|
||||
SIGSYS = Signal(31)
|
||||
SIGTERM = Signal(15)
|
||||
SIGTRAP = Signal(5)
|
||||
SIGTSTP = Signal(20)
|
||||
SIGTTIN = Signal(21)
|
||||
SIGTTOU = Signal(22)
|
||||
SIGUNUSED = Signal(31)
|
||||
SIGURG = Signal(23)
|
||||
SIGUSR1 = Signal(10)
|
||||
SIGUSR2 = Signal(12)
|
||||
SIGVTALRM = Signal(26)
|
||||
SIGWINCH = Signal(28)
|
||||
SIGXCPU = Signal(24)
|
||||
SIGXFSZ = Signal(25)
|
||||
)
|
||||
|
||||
// SignalSet is a signal mask with a bit corresponding to each signal.
|
||||
//
|
||||
// +marshal
|
||||
type SignalSet uint64
|
||||
|
||||
// SignalSetSize is the size in bytes of a SignalSet.
|
||||
const SignalSetSize = 8
|
||||
|
||||
// MakeSignalSet returns SignalSet with the bit corresponding to each of the
|
||||
// given signals set.
|
||||
func MakeSignalSet(sigs ...Signal) SignalSet {
|
||||
indices := make([]int, len(sigs))
|
||||
for i, sig := range sigs {
|
||||
indices[i] = sig.Index()
|
||||
}
|
||||
return SignalSet(bits.Mask64(indices...))
|
||||
}
|
||||
|
||||
// SignalSetOf returns a SignalSet with a single signal set.
|
||||
func SignalSetOf(sig Signal) SignalSet {
|
||||
return SignalSet(bits.MaskOf64(sig.Index()))
|
||||
}
|
||||
|
||||
// ForEachSignal invokes f for each signal set in the given mask.
|
||||
func ForEachSignal(mask SignalSet, f func(sig Signal)) {
|
||||
bits.ForEachSetBit64(uint64(mask), func(i int) {
|
||||
f(Signal(i + 1))
|
||||
})
|
||||
}
|
||||
|
||||
// 'how' values for rt_sigprocmask(2).
|
||||
const (
|
||||
// SIG_BLOCK blocks the signals in the set.
|
||||
SIG_BLOCK = 0
|
||||
|
||||
// SIG_UNBLOCK blocks the signals in the set.
|
||||
SIG_UNBLOCK = 1
|
||||
|
||||
// SIG_SETMASK sets the signal mask to set.
|
||||
SIG_SETMASK = 2
|
||||
)
|
||||
|
||||
// Signal actions for rt_sigaction(2), from uapi/asm-generic/signal-defs.h.
|
||||
const (
|
||||
// SIG_DFL performs the default action.
|
||||
SIG_DFL = 0
|
||||
|
||||
// SIG_IGN ignores the signal.
|
||||
SIG_IGN = 1
|
||||
)
|
||||
|
||||
// Signal action flags for rt_sigaction(2), from uapi/asm-generic/signal.h.
|
||||
const (
|
||||
SA_NOCLDSTOP = 0x00000001
|
||||
SA_NOCLDWAIT = 0x00000002
|
||||
SA_SIGINFO = 0x00000004
|
||||
SA_RESTORER = 0x04000000
|
||||
SA_ONSTACK = 0x08000000
|
||||
SA_RESTART = 0x10000000
|
||||
SA_NODEFER = 0x40000000
|
||||
SA_RESETHAND = 0x80000000
|
||||
SA_NOMASK = SA_NODEFER
|
||||
SA_ONESHOT = SA_RESETHAND
|
||||
)
|
||||
|
||||
// Signal stack flags for signalstack(2), from include/uapi/linux/signal.h.
|
||||
const (
|
||||
SS_ONSTACK = 1
|
||||
SS_DISABLE = 2
|
||||
)
|
||||
|
||||
// SIGPOLL si_codes.
|
||||
const (
|
||||
// SI_POLL is defined as __SI_POLL in Linux 2.6.
|
||||
SI_POLL = 2 << 16
|
||||
|
||||
// POLL_IN indicates that data input available.
|
||||
POLL_IN = SI_POLL | 1
|
||||
|
||||
// POLL_OUT indicates that output buffers available.
|
||||
POLL_OUT = SI_POLL | 2
|
||||
|
||||
// POLL_MSG indicates that an input message available.
|
||||
POLL_MSG = SI_POLL | 3
|
||||
|
||||
// POLL_ERR indicates that there was an i/o error.
|
||||
POLL_ERR = SI_POLL | 4
|
||||
|
||||
// POLL_PRI indicates that a high priority input available.
|
||||
POLL_PRI = SI_POLL | 5
|
||||
|
||||
// POLL_HUP indicates that a device disconnected.
|
||||
POLL_HUP = SI_POLL | 6
|
||||
)
|
||||
|
||||
// Possible values for si_code.
|
||||
const (
|
||||
// SI_USER is sent by kill, sigsend, raise.
|
||||
SI_USER = 0
|
||||
|
||||
// SI_KERNEL is sent by the kernel from somewhere.
|
||||
SI_KERNEL = 0x80
|
||||
|
||||
// SI_QUEUE is sent by sigqueue.
|
||||
SI_QUEUE = -1
|
||||
|
||||
// SI_TIMER is sent by timer expiration.
|
||||
SI_TIMER = -2
|
||||
|
||||
// SI_MESGQ is sent by real time mesq state change.
|
||||
SI_MESGQ = -3
|
||||
|
||||
// SI_ASYNCIO is sent by AIO completion.
|
||||
SI_ASYNCIO = -4
|
||||
|
||||
// SI_SIGIO is sent by queued SIGIO.
|
||||
SI_SIGIO = -5
|
||||
|
||||
// SI_TKILL is sent by tkill system call.
|
||||
SI_TKILL = -6
|
||||
|
||||
// SI_DETHREAD is sent by execve() killing subsidiary threads.
|
||||
SI_DETHREAD = -7
|
||||
|
||||
// SI_ASYNCNL is sent by glibc async name lookup completion.
|
||||
SI_ASYNCNL = -60
|
||||
)
|
||||
|
||||
// CLD_* codes are only meaningful for SIGCHLD.
|
||||
const (
|
||||
// CLD_EXITED indicates that a task exited.
|
||||
CLD_EXITED = 1
|
||||
|
||||
// CLD_KILLED indicates that a task was killed by a signal.
|
||||
CLD_KILLED = 2
|
||||
|
||||
// CLD_DUMPED indicates that a task was killed by a signal and then dumped
|
||||
// core.
|
||||
CLD_DUMPED = 3
|
||||
|
||||
// CLD_TRAPPED indicates that a task was stopped by ptrace.
|
||||
CLD_TRAPPED = 4
|
||||
|
||||
// CLD_STOPPED indicates that a thread group completed a group stop.
|
||||
CLD_STOPPED = 5
|
||||
|
||||
// CLD_CONTINUED indicates that a group-stopped thread group was continued.
|
||||
CLD_CONTINUED = 6
|
||||
)
|
||||
|
||||
// SYS_* codes are only meaningful for SIGSYS.
|
||||
const (
|
||||
// SYS_SECCOMP indicates that a signal originates from seccomp.
|
||||
SYS_SECCOMP = 1
|
||||
)
|
||||
|
||||
// Possible values for Sigevent.Notify, aka struct sigevent::sigev_notify.
|
||||
const (
|
||||
SIGEV_SIGNAL = 0
|
||||
SIGEV_NONE = 1
|
||||
SIGEV_THREAD = 2
|
||||
SIGEV_THREAD_ID = 4
|
||||
)
|
||||
|
||||
// SIGTRAP si_codes
|
||||
const (
|
||||
TRAP_BRKPT = 1
|
||||
TRAP_TRACE = 2
|
||||
TRAP_BRANCH = 3
|
||||
TRAP_HWBKPT = 4
|
||||
)
|
||||
|
||||
// Sigevent represents struct sigevent.
|
||||
//
|
||||
// +marshal
|
||||
type Sigevent struct {
|
||||
Value uint64 // union sigval {int, void*}
|
||||
Signo int32
|
||||
Notify int32
|
||||
|
||||
// struct sigevent here contains 48-byte union _sigev_un. However, only
|
||||
// member _tid is significant to the kernel.
|
||||
Tid int32
|
||||
UnRemainder [44]byte
|
||||
}
|
||||
|
||||
// SigAction represents struct sigaction.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type SigAction struct {
|
||||
Handler uint64
|
||||
Flags uint64
|
||||
Restorer uint64
|
||||
Mask SignalSet
|
||||
}
|
||||
|
||||
// SignalStack represents information about a user stack, and is equivalent to
|
||||
// stack_t.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type SignalStack struct {
|
||||
Addr uint64
|
||||
Flags uint32
|
||||
_ uint32
|
||||
Size uint64
|
||||
}
|
||||
|
||||
// Contains checks if the stack pointer is within this stack.
|
||||
func (s *SignalStack) Contains(sp hostarch.Addr) bool {
|
||||
return hostarch.Addr(s.Addr) < sp && sp <= hostarch.Addr(s.Addr+s.Size)
|
||||
}
|
||||
|
||||
// Top returns the stack's top address.
|
||||
func (s *SignalStack) Top() hostarch.Addr {
|
||||
return hostarch.Addr(s.Addr + s.Size)
|
||||
}
|
||||
|
||||
// IsEnabled returns true iff this signal stack is marked as enabled.
|
||||
func (s *SignalStack) IsEnabled() bool {
|
||||
return s.Flags&SS_DISABLE == 0
|
||||
}
|
||||
|
||||
// SignalInfo represents information about a signal being delivered, and is
|
||||
// equivalent to struct siginfo in linux kernel(linux/include/uapi/asm-generic/siginfo.h).
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type SignalInfo struct {
|
||||
Signo int32 // Signal number
|
||||
Errno int32 // Errno value
|
||||
Code int32 // Signal code
|
||||
_ uint32
|
||||
|
||||
// struct siginfo::_sifields is a union. In SignalInfo, fields in the union
|
||||
// are accessed through methods.
|
||||
//
|
||||
// For reference, here is the definition of _sifields: (_sigfault._trapno,
|
||||
// which does not exist on x86, omitted for clarity)
|
||||
//
|
||||
// union {
|
||||
// int _pad[SI_PAD_SIZE];
|
||||
//
|
||||
// /* kill() */
|
||||
// struct {
|
||||
// __kernel_pid_t _pid; /* sender's pid */
|
||||
// __ARCH_SI_UID_T _uid; /* sender's uid */
|
||||
// } _kill;
|
||||
//
|
||||
// /* POSIX.1b timers */
|
||||
// struct {
|
||||
// __kernel_timer_t _tid; /* timer id */
|
||||
// int _overrun; /* overrun count */
|
||||
// char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
|
||||
// sigval_t _sigval; /* same as below */
|
||||
// int _sys_private; /* not to be passed to user */
|
||||
// } _timer;
|
||||
//
|
||||
// /* POSIX.1b signals */
|
||||
// struct {
|
||||
// __kernel_pid_t _pid; /* sender's pid */
|
||||
// __ARCH_SI_UID_T _uid; /* sender's uid */
|
||||
// sigval_t _sigval;
|
||||
// } _rt;
|
||||
//
|
||||
// /* SIGCHLD */
|
||||
// struct {
|
||||
// __kernel_pid_t _pid; /* which child */
|
||||
// __ARCH_SI_UID_T _uid; /* sender's uid */
|
||||
// int _status; /* exit code */
|
||||
// __ARCH_SI_CLOCK_T _utime;
|
||||
// __ARCH_SI_CLOCK_T _stime;
|
||||
// } _sigchld;
|
||||
//
|
||||
// /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
||||
// struct {
|
||||
// void *_addr; /* faulting insn/memory ref. */
|
||||
// short _addr_lsb; /* LSB of the reported address */
|
||||
// } _sigfault;
|
||||
//
|
||||
// /* SIGPOLL */
|
||||
// struct {
|
||||
// __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
|
||||
// int _fd;
|
||||
// } _sigpoll;
|
||||
//
|
||||
// /* SIGSYS */
|
||||
// struct {
|
||||
// void *_call_addr; /* calling user insn */
|
||||
// int _syscall; /* triggering system call number */
|
||||
// unsigned int _arch; /* AUDIT_ARCH_* of syscall */
|
||||
// } _sigsys;
|
||||
// } _sifields;
|
||||
//
|
||||
// _sifields is padded so that the size of siginfo is SI_MAX_SIZE = 128
|
||||
// bytes.
|
||||
Fields [128 - 16]byte
|
||||
}
|
||||
|
||||
// FixSignalCodeForUser fixes up si_code.
|
||||
//
|
||||
// The si_code we get from Linux may contain the kernel-specific code in the
|
||||
// top 16 bits if it's positive (e.g., from ptrace). Linux's
|
||||
// copy_siginfo_to_user does:
|
||||
// err |= __put_user((short)from->si_code, &to->si_code);
|
||||
// to mask out those bits and we need to do the same.
|
||||
func (s *SignalInfo) FixSignalCodeForUser() {
|
||||
if s.Code > 0 {
|
||||
s.Code &= 0x0000ffff
|
||||
}
|
||||
}
|
||||
|
||||
// PID returns the si_pid field.
|
||||
func (s *SignalInfo) PID() int32 {
|
||||
return int32(hostarch.ByteOrder.Uint32(s.Fields[0:4]))
|
||||
}
|
||||
|
||||
// SetPID mutates the si_pid field.
|
||||
func (s *SignalInfo) SetPID(val int32) {
|
||||
hostarch.ByteOrder.PutUint32(s.Fields[0:4], uint32(val))
|
||||
}
|
||||
|
||||
// UID returns the si_uid field.
|
||||
func (s *SignalInfo) UID() int32 {
|
||||
return int32(hostarch.ByteOrder.Uint32(s.Fields[4:8]))
|
||||
}
|
||||
|
||||
// SetUID mutates the si_uid field.
|
||||
func (s *SignalInfo) SetUID(val int32) {
|
||||
hostarch.ByteOrder.PutUint32(s.Fields[4:8], uint32(val))
|
||||
}
|
||||
|
||||
// Sigval returns the sigval field, which is aliased to both si_int and si_ptr.
|
||||
func (s *SignalInfo) Sigval() uint64 {
|
||||
return hostarch.ByteOrder.Uint64(s.Fields[8:16])
|
||||
}
|
||||
|
||||
// SetSigval mutates the sigval field.
|
||||
func (s *SignalInfo) SetSigval(val uint64) {
|
||||
hostarch.ByteOrder.PutUint64(s.Fields[8:16], val)
|
||||
}
|
||||
|
||||
// TimerID returns the si_timerid field.
|
||||
func (s *SignalInfo) TimerID() TimerID {
|
||||
return TimerID(hostarch.ByteOrder.Uint32(s.Fields[0:4]))
|
||||
}
|
||||
|
||||
// SetTimerID sets the si_timerid field.
|
||||
func (s *SignalInfo) SetTimerID(val TimerID) {
|
||||
hostarch.ByteOrder.PutUint32(s.Fields[0:4], uint32(val))
|
||||
}
|
||||
|
||||
// Overrun returns the si_overrun field.
|
||||
func (s *SignalInfo) Overrun() int32 {
|
||||
return int32(hostarch.ByteOrder.Uint32(s.Fields[4:8]))
|
||||
}
|
||||
|
||||
// SetOverrun sets the si_overrun field.
|
||||
func (s *SignalInfo) SetOverrun(val int32) {
|
||||
hostarch.ByteOrder.PutUint32(s.Fields[4:8], uint32(val))
|
||||
}
|
||||
|
||||
// Addr returns the si_addr field.
|
||||
func (s *SignalInfo) Addr() uint64 {
|
||||
return hostarch.ByteOrder.Uint64(s.Fields[0:8])
|
||||
}
|
||||
|
||||
// SetAddr sets the si_addr field.
|
||||
func (s *SignalInfo) SetAddr(val uint64) {
|
||||
hostarch.ByteOrder.PutUint64(s.Fields[0:8], val)
|
||||
}
|
||||
|
||||
// Status returns the si_status field.
|
||||
func (s *SignalInfo) Status() int32 {
|
||||
return int32(hostarch.ByteOrder.Uint32(s.Fields[8:12]))
|
||||
}
|
||||
|
||||
// SetStatus mutates the si_status field.
|
||||
func (s *SignalInfo) SetStatus(val int32) {
|
||||
hostarch.ByteOrder.PutUint32(s.Fields[8:12], uint32(val))
|
||||
}
|
||||
|
||||
// CallAddr returns the si_call_addr field.
|
||||
func (s *SignalInfo) CallAddr() uint64 {
|
||||
return hostarch.ByteOrder.Uint64(s.Fields[0:8])
|
||||
}
|
||||
|
||||
// SetCallAddr mutates the si_call_addr field.
|
||||
func (s *SignalInfo) SetCallAddr(val uint64) {
|
||||
hostarch.ByteOrder.PutUint64(s.Fields[0:8], val)
|
||||
}
|
||||
|
||||
// Syscall returns the si_syscall field.
|
||||
func (s *SignalInfo) Syscall() int32 {
|
||||
return int32(hostarch.ByteOrder.Uint32(s.Fields[8:12]))
|
||||
}
|
||||
|
||||
// SetSyscall mutates the si_syscall field.
|
||||
func (s *SignalInfo) SetSyscall(val int32) {
|
||||
hostarch.ByteOrder.PutUint32(s.Fields[8:12], uint32(val))
|
||||
}
|
||||
|
||||
// Arch returns the si_arch field.
|
||||
func (s *SignalInfo) Arch() uint32 {
|
||||
return hostarch.ByteOrder.Uint32(s.Fields[12:16])
|
||||
}
|
||||
|
||||
// SetArch mutates the si_arch field.
|
||||
func (s *SignalInfo) SetArch(val uint32) {
|
||||
hostarch.ByteOrder.PutUint32(s.Fields[12:16], val)
|
||||
}
|
||||
|
||||
// Band returns the si_band field.
|
||||
func (s *SignalInfo) Band() int64 {
|
||||
return int64(hostarch.ByteOrder.Uint64(s.Fields[0:8]))
|
||||
}
|
||||
|
||||
// SetBand mutates the si_band field.
|
||||
func (s *SignalInfo) SetBand(val int64) {
|
||||
// Note: this assumes the platform uses `long` as `__ARCH_SI_BAND_T`.
|
||||
// On some platforms, which gVisor doesn't support, `__ARCH_SI_BAND_T` is
|
||||
// `int`. See siginfo.h.
|
||||
hostarch.ByteOrder.PutUint64(s.Fields[0:8], uint64(val))
|
||||
}
|
||||
|
||||
// FD returns the si_fd field.
|
||||
func (s *SignalInfo) FD() uint32 {
|
||||
return hostarch.ByteOrder.Uint32(s.Fields[8:12])
|
||||
}
|
||||
|
||||
// SetFD mutates the si_fd field.
|
||||
func (s *SignalInfo) SetFD(val uint32) {
|
||||
hostarch.ByteOrder.PutUint32(s.Fields[8:12], val)
|
||||
}
|
||||
47
pkg/abi/linux/signalfd.go
Normal file
47
pkg/abi/linux/signalfd.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
const (
|
||||
// SFD_NONBLOCK is a signalfd(2) flag.
|
||||
SFD_NONBLOCK = 0o0004000
|
||||
|
||||
// SFD_CLOEXEC is a signalfd(2) flag.
|
||||
SFD_CLOEXEC = 0o2000000
|
||||
)
|
||||
|
||||
// SignalfdSiginfo is the siginfo encoding for signalfds.
|
||||
//
|
||||
// +marshal
|
||||
type SignalfdSiginfo struct {
|
||||
Signo uint32
|
||||
Errno int32
|
||||
Code int32
|
||||
PID uint32
|
||||
UID uint32
|
||||
FD int32
|
||||
TID uint32
|
||||
Band uint32
|
||||
Overrun uint32
|
||||
TrapNo uint32
|
||||
Status int32
|
||||
Int int32
|
||||
Ptr uint64
|
||||
UTime uint64
|
||||
STime uint64
|
||||
Addr uint64
|
||||
AddrLSB uint16
|
||||
_ [48]uint8 `marshal:"unaligned"`
|
||||
}
|
||||
740
pkg/abi/linux/socket.go
Normal file
740
pkg/abi/linux/socket.go
Normal file
|
|
@ -0,0 +1,740 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"github.com/sagernet/gvisor/pkg/marshal"
|
||||
)
|
||||
|
||||
// Address families, from linux/socket.h.
|
||||
const (
|
||||
AF_UNSPEC = 0
|
||||
AF_UNIX = 1
|
||||
AF_INET = 2
|
||||
AF_AX25 = 3
|
||||
AF_IPX = 4
|
||||
AF_APPLETALK = 5
|
||||
AF_NETROM = 6
|
||||
AF_BRIDGE = 7
|
||||
AF_ATMPVC = 8
|
||||
AF_X25 = 9
|
||||
AF_INET6 = 10
|
||||
AF_ROSE = 11
|
||||
AF_DECnet = 12
|
||||
AF_NETBEUI = 13
|
||||
AF_SECURITY = 14
|
||||
AF_KEY = 15
|
||||
AF_NETLINK = 16
|
||||
AF_PACKET = 17
|
||||
AF_ASH = 18
|
||||
AF_ECONET = 19
|
||||
AF_ATMSVC = 20
|
||||
AF_RDS = 21
|
||||
AF_SNA = 22
|
||||
AF_IRDA = 23
|
||||
AF_PPPOX = 24
|
||||
AF_WANPIPE = 25
|
||||
AF_LLC = 26
|
||||
AF_IB = 27
|
||||
AF_MPLS = 28
|
||||
AF_CAN = 29
|
||||
AF_TIPC = 30
|
||||
AF_BLUETOOTH = 31
|
||||
AF_IUCV = 32
|
||||
AF_RXRPC = 33
|
||||
AF_ISDN = 34
|
||||
AF_PHONET = 35
|
||||
AF_IEEE802154 = 36
|
||||
AF_CAIF = 37
|
||||
AF_ALG = 38
|
||||
AF_NFC = 39
|
||||
AF_VSOCK = 40
|
||||
)
|
||||
|
||||
// sendmsg(2)/recvmsg(2) flags, from linux/socket.h.
|
||||
const (
|
||||
MSG_OOB = 0x1
|
||||
MSG_PEEK = 0x2
|
||||
MSG_DONTROUTE = 0x4
|
||||
MSG_TRYHARD = 0x4
|
||||
MSG_CTRUNC = 0x8
|
||||
MSG_PROBE = 0x10
|
||||
MSG_TRUNC = 0x20
|
||||
MSG_DONTWAIT = 0x40
|
||||
MSG_EOR = 0x80
|
||||
MSG_WAITALL = 0x100
|
||||
MSG_FIN = 0x200
|
||||
MSG_EOF = MSG_FIN
|
||||
MSG_SYN = 0x400
|
||||
MSG_CONFIRM = 0x800
|
||||
MSG_RST = 0x1000
|
||||
MSG_ERRQUEUE = 0x2000
|
||||
MSG_NOSIGNAL = 0x4000
|
||||
MSG_MORE = 0x8000
|
||||
MSG_WAITFORONE = 0x10000
|
||||
MSG_SENDPAGE_NOTLAST = 0x20000
|
||||
MSG_ZEROCOPY = 0x4000000
|
||||
MSG_FASTOPEN = 0x20000000
|
||||
MSG_CMSG_CLOEXEC = 0x40000000
|
||||
)
|
||||
|
||||
// Set/get socket option levels, from socket.h.
|
||||
const (
|
||||
SOL_IP = 0
|
||||
SOL_SOCKET = 1
|
||||
SOL_TCP = 6
|
||||
SOL_UDP = 17
|
||||
SOL_IPV6 = 41
|
||||
SOL_ICMPV6 = 58
|
||||
SOL_RAW = 255
|
||||
SOL_PACKET = 263
|
||||
SOL_NETLINK = 270
|
||||
)
|
||||
|
||||
// A SockType is a type (as opposed to family) of sockets. These are enumerated
|
||||
// below as SOCK_* constants.
|
||||
type SockType int
|
||||
|
||||
// Socket types, from linux/net.h.
|
||||
const (
|
||||
SOCK_STREAM SockType = 1
|
||||
SOCK_DGRAM SockType = 2
|
||||
SOCK_RAW SockType = 3
|
||||
SOCK_RDM SockType = 4
|
||||
SOCK_SEQPACKET SockType = 5
|
||||
SOCK_DCCP SockType = 6
|
||||
SOCK_PACKET SockType = 10
|
||||
)
|
||||
|
||||
// SOCK_TYPE_MASK covers all of the above socket types. The remaining bits are
|
||||
// flags. From linux/net.h.
|
||||
const SOCK_TYPE_MASK = 0xf
|
||||
|
||||
// socket(2)/socketpair(2)/accept4(2) flags, from linux/net.h.
|
||||
const (
|
||||
SOCK_CLOEXEC = O_CLOEXEC
|
||||
SOCK_NONBLOCK = O_NONBLOCK
|
||||
)
|
||||
|
||||
// shutdown(2) how commands, from <linux/net.h>.
|
||||
const (
|
||||
SHUT_RD = 0
|
||||
SHUT_WR = 1
|
||||
SHUT_RDWR = 2
|
||||
)
|
||||
|
||||
// Packet types from <linux/if_packet.h>
|
||||
const (
|
||||
PACKET_HOST = 0 // To us
|
||||
PACKET_BROADCAST = 1 // To all
|
||||
PACKET_MULTICAST = 2 // To group
|
||||
PACKET_OTHERHOST = 3 // To someone else
|
||||
PACKET_OUTGOING = 4 // Outgoing of any type
|
||||
)
|
||||
|
||||
// Packet socket options from <linux/if_packet.h>
|
||||
const (
|
||||
PACKET_ADD_MEMBERSHIP = 1
|
||||
PACKET_RX_RING = 5
|
||||
PACKET_STATISTICS = 6
|
||||
PACKET_AUXDATA = 8
|
||||
PACKET_VERSION = 10
|
||||
PACKET_HDRLEN = 11
|
||||
PACKET_RESERVE = 12
|
||||
)
|
||||
|
||||
// Statuses for a frame in a packet_mmap ring buffer from <linux/if_packet.h>.
|
||||
const (
|
||||
TP_STATUS_KERNEL = 0
|
||||
TP_STATUS_USER = 0x1
|
||||
TP_STATUS_COPY = 0x2
|
||||
TP_STATUS_LOSING = 0x4
|
||||
TP_STATUS_CSUM_NOT_READY = 0x8
|
||||
TP_STATUS_VLAN_VALID = 0x10
|
||||
TP_STATUS_BLK_TMO = 0x20
|
||||
TP_STATUS_VLAN_TPID_VALID = 0x40
|
||||
TP_STATUS_CSUM_VALID = 0x80
|
||||
TP_STATUS_GSO_TCP = 0x100
|
||||
)
|
||||
|
||||
// TpacketReq is the request for a packet_mmap ring buffer from
|
||||
// <linux/if_packet.h>.
|
||||
//
|
||||
// +marshal
|
||||
type TpacketReq struct {
|
||||
TpBlockSize uint32
|
||||
TpBlockNr uint32
|
||||
TpFrameSize uint32
|
||||
TpFrameNr uint32
|
||||
}
|
||||
|
||||
// TpacketHdr is the header for a frame in a packet_mmap ring buffer from
|
||||
// <linux/if_packet.h>.
|
||||
//
|
||||
// +marshal
|
||||
type TpacketHdr struct {
|
||||
TpStatus uint64
|
||||
TpLen uint32
|
||||
TpSnaplen uint32
|
||||
TpMac uint16
|
||||
TpNet uint16
|
||||
TpSec uint32
|
||||
TpUsec uint32
|
||||
_ [4]uint8
|
||||
}
|
||||
|
||||
// Tpacket2Hdr is the header for a frame in a packet_mmap ring buffer from
|
||||
// <linux/if_packet.h>.
|
||||
//
|
||||
// +marshal
|
||||
type Tpacket2Hdr struct {
|
||||
TpStatus uint32
|
||||
TpLen uint32
|
||||
TpSnaplen uint32
|
||||
TpMac uint16
|
||||
TpNet uint16
|
||||
TpSec uint32
|
||||
TpNSec uint32
|
||||
TpVlanTci uint16
|
||||
TpVlanTpid uint16
|
||||
_ [4]uint8
|
||||
}
|
||||
|
||||
// TpacketStats is the statistics for a packet_mmap ring buffer from
|
||||
// <linux/if_packet.h>.
|
||||
//
|
||||
// +marshal
|
||||
type TpacketStats struct {
|
||||
Packets uint32
|
||||
Dropped uint32
|
||||
}
|
||||
|
||||
// TpacketAlignment is the alignment of a frame in a packet_mmap ring buffer
|
||||
// from <linux/if_packet.h>.
|
||||
const (
|
||||
TPACKET_ALIGNMENT = 16
|
||||
)
|
||||
|
||||
// TPACKET_V1 is the version of a packet_mmap ring buffer from
|
||||
// <linux/if_packet.h> that is implemented in gVisor.
|
||||
const (
|
||||
// TPACKET_V1 is the default version of PACKET_MMAP.
|
||||
TPACKET_V1 = iota
|
||||
// TPACKET_V2 is the version of PACKET_MMAP for tpacket2_hdr.
|
||||
TPACKET_V2
|
||||
)
|
||||
|
||||
var (
|
||||
// TPACKET_HDRLEN is the length of a TpacketHdr from <linux/if_packet.h>.
|
||||
TPACKET_HDRLEN = TPacketAlign(uint32((*TpacketHdr)(nil).SizeBytes()) + uint32((*SockAddrLink)(nil).SizeBytes()))
|
||||
// TPACKET2_HDRLEN is the length of a Tpacket2Hdr from <linux/if_packet.h>.
|
||||
TPACKET2_HDRLEN = TPacketAlign(uint32((*Tpacket2Hdr)(nil).SizeBytes()) + uint32((*SockAddrLink)(nil).SizeBytes()))
|
||||
)
|
||||
|
||||
// TPacketAlign aligns a value to the alignment of a TPacket.
|
||||
func TPacketAlign(x uint32) uint32 {
|
||||
return (x + TPACKET_ALIGNMENT - 1) &^ (TPACKET_ALIGNMENT - 1)
|
||||
}
|
||||
|
||||
// Socket options from socket.h.
|
||||
const (
|
||||
SO_DEBUG = 1
|
||||
SO_REUSEADDR = 2
|
||||
SO_TYPE = 3
|
||||
SO_ERROR = 4
|
||||
SO_DONTROUTE = 5
|
||||
SO_BROADCAST = 6
|
||||
SO_SNDBUF = 7
|
||||
SO_RCVBUF = 8
|
||||
SO_KEEPALIVE = 9
|
||||
SO_OOBINLINE = 10
|
||||
SO_NO_CHECK = 11
|
||||
SO_PRIORITY = 12
|
||||
SO_LINGER = 13
|
||||
SO_BSDCOMPAT = 14
|
||||
SO_REUSEPORT = 15
|
||||
SO_PASSCRED = 16
|
||||
SO_PEERCRED = 17
|
||||
SO_RCVLOWAT = 18
|
||||
SO_SNDLOWAT = 19
|
||||
SO_RCVTIMEO = 20
|
||||
SO_SNDTIMEO = 21
|
||||
SO_BINDTODEVICE = 25
|
||||
SO_ATTACH_FILTER = 26
|
||||
SO_DETACH_FILTER = 27
|
||||
SO_GET_FILTER = SO_ATTACH_FILTER
|
||||
SO_PEERNAME = 28
|
||||
SO_TIMESTAMP = 29
|
||||
SO_ACCEPTCONN = 30
|
||||
SO_PEERSEC = 31
|
||||
SO_SNDBUFFORCE = 32
|
||||
SO_RCVBUFFORCE = 33
|
||||
SO_PASSSEC = 34
|
||||
SO_TIMESTAMPNS = 35
|
||||
SO_MARK = 36
|
||||
SO_TIMESTAMPING = 37
|
||||
SO_PROTOCOL = 38
|
||||
SO_DOMAIN = 39
|
||||
SO_RXQ_OVFL = 40
|
||||
SO_WIFI_STATUS = 41
|
||||
SO_PEEK_OFF = 42
|
||||
SO_NOFCS = 43
|
||||
SO_LOCK_FILTER = 44
|
||||
SO_SELECT_ERR_QUEUE = 45
|
||||
SO_BUSY_POLL = 46
|
||||
SO_MAX_PACING_RATE = 47
|
||||
SO_BPF_EXTENSIONS = 48
|
||||
SO_INCOMING_CPU = 49
|
||||
SO_ATTACH_BPF = 50
|
||||
SO_ATTACH_REUSEPORT_CBPF = 51
|
||||
SO_ATTACH_REUSEPORT_EBPF = 52
|
||||
SO_CNX_ADVICE = 53
|
||||
SO_MEMINFO = 55
|
||||
SO_INCOMING_NAPI_ID = 56
|
||||
SO_COOKIE = 57
|
||||
SO_PEERGROUPS = 59
|
||||
SO_ZEROCOPY = 60
|
||||
SO_TXTIME = 61
|
||||
SO_BINDTOIFINDEX = 62
|
||||
SO_TIMESTAMP_OLD = 29
|
||||
SO_TIMESTAMPNS_OLD = 35
|
||||
SO_TIMESTAMPING_OLD = 37
|
||||
SO_TIMESTAMP_NEW = 63
|
||||
SO_TIMESTAMPNS_NEW = 64
|
||||
SO_TIMESTAMPING_NEW = 65
|
||||
SO_RCVTIMEO_NEW = 66
|
||||
SO_SNDTIMEO_NEW = 67
|
||||
SO_DETACH_REUSEPORT_BPF = 68
|
||||
SO_PREFER_BUSY_POLL = 69
|
||||
SO_BUSY_POLL_BUDGET = 70
|
||||
SO_NETNS_COOKIE = 71
|
||||
SO_BUF_LOCK = 72
|
||||
SO_RESERVE_MEM = 73
|
||||
SO_TXREHASH = 74
|
||||
SO_RCVMARK = 75
|
||||
SO_PASSPIDFD = 76
|
||||
SO_PEERPIDFD = 77
|
||||
SO_DEVMEM_LINEAR = 78
|
||||
SO_DEVMEM_DMABUF = 79
|
||||
SO_DEVMEM_DONTNEED = 80
|
||||
SO_RCVPRIORITY = 82
|
||||
)
|
||||
|
||||
// enum socket_state, from uapi/linux/net.h.
|
||||
const (
|
||||
SS_FREE = 0 // Not allocated.
|
||||
SS_UNCONNECTED = 1 // Unconnected to any socket.
|
||||
SS_CONNECTING = 2 // In process of connecting.
|
||||
SS_CONNECTED = 3 // Connected to socket.
|
||||
SS_DISCONNECTING = 4 // In process of disconnecting.
|
||||
)
|
||||
|
||||
// TCP protocol states, from include/net/tcp_states.h.
|
||||
const (
|
||||
TCP_ESTABLISHED uint32 = iota + 1
|
||||
TCP_SYN_SENT
|
||||
TCP_SYN_RECV
|
||||
TCP_FIN_WAIT1
|
||||
TCP_FIN_WAIT2
|
||||
TCP_TIME_WAIT
|
||||
TCP_CLOSE
|
||||
TCP_CLOSE_WAIT
|
||||
TCP_LAST_ACK
|
||||
TCP_LISTEN
|
||||
TCP_CLOSING
|
||||
TCP_NEW_SYN_RECV
|
||||
)
|
||||
|
||||
// SockAddrMax is the maximum size of a struct sockaddr, from
|
||||
// uapi/linux/socket.h.
|
||||
const SockAddrMax = 128
|
||||
|
||||
// InetAddr is struct in_addr, from uapi/linux/in.h.
|
||||
//
|
||||
// +marshal
|
||||
type InetAddr [4]byte
|
||||
|
||||
// SizeOfInetAddr is the size of InetAddr.
|
||||
var SizeOfInetAddr = uint32((*InetAddr)(nil).SizeBytes())
|
||||
|
||||
// SockAddrInet is struct sockaddr_in, from uapi/linux/in.h.
|
||||
//
|
||||
// +marshal
|
||||
type SockAddrInet struct {
|
||||
Family uint16
|
||||
Port uint16
|
||||
Addr InetAddr
|
||||
_ [8]uint8 // pad to sizeof(struct sockaddr).
|
||||
}
|
||||
|
||||
// Inet6MulticastRequest is struct ipv6_mreq, from uapi/linux/in6.h.
|
||||
//
|
||||
// +marshal
|
||||
type Inet6MulticastRequest struct {
|
||||
MulticastAddr Inet6Addr
|
||||
InterfaceIndex int32
|
||||
}
|
||||
|
||||
// InetMulticastRequest is struct ip_mreq, from uapi/linux/in.h.
|
||||
//
|
||||
// +marshal
|
||||
type InetMulticastRequest struct {
|
||||
MulticastAddr InetAddr
|
||||
InterfaceAddr InetAddr
|
||||
}
|
||||
|
||||
// InetMulticastRequestWithNIC is struct ip_mreqn, from uapi/linux/in.h.
|
||||
//
|
||||
// +marshal
|
||||
type InetMulticastRequestWithNIC struct {
|
||||
InetMulticastRequest
|
||||
InterfaceIndex int32
|
||||
}
|
||||
|
||||
// Inet6Addr is struct in6_addr, from uapi/linux/in6.h.
|
||||
//
|
||||
// +marshal
|
||||
type Inet6Addr [16]byte
|
||||
|
||||
// SockAddrInet6 is struct sockaddr_in6, from uapi/linux/in6.h.
|
||||
//
|
||||
// +marshal
|
||||
type SockAddrInet6 struct {
|
||||
Family uint16
|
||||
Port uint16
|
||||
Flowinfo uint32
|
||||
Addr [16]byte
|
||||
Scope_id uint32
|
||||
}
|
||||
|
||||
// SockAddrLink is a struct sockaddr_ll, from uapi/linux/if_packet.h.
|
||||
//
|
||||
// +marshal
|
||||
type SockAddrLink struct {
|
||||
Family uint16
|
||||
Protocol uint16
|
||||
InterfaceIndex int32
|
||||
ARPHardwareType uint16
|
||||
PacketType byte
|
||||
HardwareAddrLen byte
|
||||
HardwareAddr [8]byte
|
||||
}
|
||||
|
||||
// UnixPathMax is the maximum length of the path in an AF_UNIX socket.
|
||||
//
|
||||
// From uapi/linux/un.h.
|
||||
const UnixPathMax = 108
|
||||
|
||||
// SockAddrUnix is struct sockaddr_un, from uapi/linux/un.h.
|
||||
//
|
||||
// +marshal
|
||||
type SockAddrUnix struct {
|
||||
Family uint16
|
||||
Path [UnixPathMax]int8
|
||||
}
|
||||
|
||||
// SockAddr represents a union of valid socket address types. This is logically
|
||||
// equivalent to struct sockaddr. SockAddr ensures that a well-defined set of
|
||||
// types can be used as socket addresses.
|
||||
type SockAddr interface {
|
||||
marshal.Marshallable
|
||||
|
||||
// implementsSockAddr exists purely to allow a type to indicate that they
|
||||
// implement this interface. This method is a no-op and shouldn't be called.
|
||||
implementsSockAddr()
|
||||
}
|
||||
|
||||
func (s *SockAddrInet) implementsSockAddr() {}
|
||||
func (s *SockAddrInet6) implementsSockAddr() {}
|
||||
func (s *SockAddrLink) implementsSockAddr() {}
|
||||
func (s *SockAddrUnix) implementsSockAddr() {}
|
||||
func (s *SockAddrNetlink) implementsSockAddr() {}
|
||||
|
||||
// Linger is struct linger, from include/linux/socket.h.
|
||||
//
|
||||
// +marshal
|
||||
type Linger struct {
|
||||
OnOff int32
|
||||
Linger int32
|
||||
}
|
||||
|
||||
// SizeOfLinger is the binary size of a Linger struct.
|
||||
const SizeOfLinger = 8
|
||||
|
||||
// TCPInfo is a collection of TCP statistics.
|
||||
//
|
||||
// From uapi/linux/tcp.h. Newer versions of Linux continue to add new fields to
|
||||
// the end of this struct or within existing unused space, so its size grows
|
||||
// over time. The current iteration is based on linux v4.17. New versions are
|
||||
// always backwards compatible.
|
||||
//
|
||||
// +marshal
|
||||
type TCPInfo struct {
|
||||
// State is the state of the connection.
|
||||
State uint8
|
||||
|
||||
// CaState is the congestion control state.
|
||||
CaState uint8
|
||||
|
||||
// Retransmits is the number of retransmissions triggered by RTO.
|
||||
Retransmits uint8
|
||||
|
||||
// Probes is the number of unanswered zero window probes.
|
||||
Probes uint8
|
||||
|
||||
// BackOff indicates exponential backoff.
|
||||
Backoff uint8
|
||||
|
||||
// Options indicates the options enabled for the connection.
|
||||
Options uint8
|
||||
|
||||
// WindowScale is the combination of snd_wscale (first 4 bits) and
|
||||
// rcv_wscale (second 4 bits)
|
||||
WindowScale uint8
|
||||
|
||||
// DeliveryRateAppLimited is a boolean and only the first bit is
|
||||
// meaningful.
|
||||
DeliveryRateAppLimited uint8
|
||||
|
||||
// RTO is the retransmission timeout.
|
||||
RTO uint32
|
||||
|
||||
// ATO is the acknowledgement timeout interval.
|
||||
ATO uint32
|
||||
|
||||
// SndMss is the send maximum segment size.
|
||||
SndMss uint32
|
||||
|
||||
// RcvMss is the receive maximum segment size.
|
||||
RcvMss uint32
|
||||
|
||||
// Unacked is the number of packets sent but not acknowledged.
|
||||
Unacked uint32
|
||||
|
||||
// Sacked is the number of packets which are selectively acknowledged.
|
||||
Sacked uint32
|
||||
|
||||
// Lost is the number of packets marked as lost.
|
||||
Lost uint32
|
||||
|
||||
// Retrans is the number of retransmitted packets.
|
||||
Retrans uint32
|
||||
|
||||
// Fackets is not used and is always zero.
|
||||
Fackets uint32
|
||||
|
||||
// Times.
|
||||
LastDataSent uint32
|
||||
LastAckSent uint32
|
||||
LastDataRecv uint32
|
||||
LastAckRecv uint32
|
||||
|
||||
// Metrics.
|
||||
PMTU uint32
|
||||
RcvSsthresh uint32
|
||||
RTT uint32
|
||||
RTTVar uint32
|
||||
SndSsthresh uint32
|
||||
SndCwnd uint32
|
||||
Advmss uint32
|
||||
Reordering uint32
|
||||
|
||||
// RcvRTT is the receiver round trip time.
|
||||
RcvRTT uint32
|
||||
|
||||
// RcvSpace is the current buffer space available for receiving data.
|
||||
RcvSpace uint32
|
||||
|
||||
// TotalRetrans is the total number of retransmits seen since the start
|
||||
// of the connection.
|
||||
TotalRetrans uint32
|
||||
|
||||
// PacingRate is the pacing rate in bytes per second.
|
||||
PacingRate uint64
|
||||
|
||||
// MaxPacingRate is the maximum pacing rate.
|
||||
MaxPacingRate uint64
|
||||
|
||||
// BytesAcked is RFC4898 tcpEStatsAppHCThruOctetsAcked.
|
||||
BytesAcked uint64
|
||||
|
||||
// BytesReceived is RFC4898 tcpEStatsAppHCThruOctetsReceived.
|
||||
BytesReceived uint64
|
||||
|
||||
// SegsOut is RFC4898 tcpEStatsPerfSegsOut.
|
||||
SegsOut uint32
|
||||
|
||||
// SegsIn is RFC4898 tcpEStatsPerfSegsIn.
|
||||
SegsIn uint32
|
||||
|
||||
// NotSentBytes is the amount of bytes in the write queue that are not
|
||||
// yet sent.
|
||||
NotSentBytes uint32
|
||||
|
||||
// MinRTT is the minimum round trip time seen in the connection.
|
||||
MinRTT uint32
|
||||
|
||||
// DataSegsIn is RFC4898 tcpEStatsDataSegsIn.
|
||||
DataSegsIn uint32
|
||||
|
||||
// DataSegsOut is RFC4898 tcpEStatsDataSegsOut.
|
||||
DataSegsOut uint32
|
||||
|
||||
// DeliveryRate is the most recent delivery rate in bytes per second.
|
||||
DeliveryRate uint64
|
||||
|
||||
// BusyTime is the time in microseconds busy sending data.
|
||||
BusyTime uint64
|
||||
|
||||
// RwndLimited is the time in microseconds limited by receive window.
|
||||
RwndLimited uint64
|
||||
|
||||
// SndBufLimited is the time in microseconds limited by send buffer.
|
||||
SndBufLimited uint64
|
||||
|
||||
// Delivered is the total data packets delivered including retransmits.
|
||||
Delivered uint32
|
||||
|
||||
// DeliveredCE is the total ECE marked data packets delivered including
|
||||
// retransmits.
|
||||
DeliveredCE uint32
|
||||
|
||||
// BytesSent is RFC4898 tcpEStatsPerfHCDataOctetsOut.
|
||||
BytesSent uint64
|
||||
|
||||
// BytesRetrans is RFC4898 tcpEStatsPerfOctetsRetrans.
|
||||
BytesRetrans uint64
|
||||
|
||||
// DSACKDups is RFC4898 tcpEStatsStackDSACKDups.
|
||||
DSACKDups uint32
|
||||
|
||||
// ReordSeen is the number of reordering events seen since the start of
|
||||
// the connection.
|
||||
ReordSeen uint32
|
||||
}
|
||||
|
||||
// SizeOfTCPInfo is the binary size of a TCPInfo struct.
|
||||
var SizeOfTCPInfo = (*TCPInfo)(nil).SizeBytes()
|
||||
|
||||
// Control message types, from linux/socket.h.
|
||||
const (
|
||||
SCM_CREDENTIALS = 0x2
|
||||
SCM_RIGHTS = 0x1
|
||||
)
|
||||
|
||||
// A ControlMessageHeader is the header for a socket control message.
|
||||
//
|
||||
// ControlMessageHeader represents struct cmsghdr from linux/socket.h.
|
||||
//
|
||||
// +marshal
|
||||
type ControlMessageHeader struct {
|
||||
Length uint64
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
// SizeOfControlMessageHeader is the binary size of a ControlMessageHeader
|
||||
// struct.
|
||||
var SizeOfControlMessageHeader = (*ControlMessageHeader)(nil).SizeBytes()
|
||||
|
||||
// A ControlMessageCredentials is an SCM_CREDENTIALS socket control message.
|
||||
//
|
||||
// ControlMessageCredentials represents struct ucred from linux/socket.h.
|
||||
//
|
||||
// +marshal
|
||||
type ControlMessageCredentials struct {
|
||||
PID int32
|
||||
UID uint32
|
||||
GID uint32
|
||||
}
|
||||
|
||||
// A ControlMessageIPPacketInfo is IP_PKTINFO socket control message.
|
||||
//
|
||||
// ControlMessageIPPacketInfo represents struct in_pktinfo from linux/in.h.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type ControlMessageIPPacketInfo struct {
|
||||
NIC int32
|
||||
LocalAddr InetAddr
|
||||
DestinationAddr InetAddr
|
||||
}
|
||||
|
||||
// ControlMessageIPv6PacketInfo represents struct in6_pktinfo from linux/ipv6.h.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type ControlMessageIPv6PacketInfo struct {
|
||||
Addr Inet6Addr
|
||||
NIC uint32
|
||||
}
|
||||
|
||||
// SizeOfControlMessageCredentials is the binary size of a
|
||||
// ControlMessageCredentials struct.
|
||||
var SizeOfControlMessageCredentials = (*ControlMessageCredentials)(nil).SizeBytes()
|
||||
|
||||
// SizeOfControlMessageRight is the size of a single element in
|
||||
// ControlMessageRights.
|
||||
const SizeOfControlMessageRight = 4
|
||||
|
||||
// SizeOfControlMessageInq is the size of a TCP_INQ control message.
|
||||
const SizeOfControlMessageInq = 4
|
||||
|
||||
// SizeOfControlMessageTOS is the size of an IP_TOS control message.
|
||||
const SizeOfControlMessageTOS = 1
|
||||
|
||||
// SizeOfControlMessageTTL is the size of an IP_TTL control message.
|
||||
const SizeOfControlMessageTTL = 4
|
||||
|
||||
// SizeOfControlMessageTClass is the size of an IPV6_TCLASS control message.
|
||||
const SizeOfControlMessageTClass = 4
|
||||
|
||||
// SizeOfControlMessageHopLimit is the size of an IPV6_HOPLIMIT control message.
|
||||
const SizeOfControlMessageHopLimit = 4
|
||||
|
||||
// SizeOfControlMessageIPPacketInfo is the size of an IP_PKTINFO control
|
||||
// message.
|
||||
const SizeOfControlMessageIPPacketInfo = 12
|
||||
|
||||
// SizeOfControlMessageIPv6PacketInfo is the size of a
|
||||
// ControlMessageIPv6PacketInfo.
|
||||
const SizeOfControlMessageIPv6PacketInfo = 20
|
||||
|
||||
// SCM_MAX_FD is the maximum number of FDs accepted in a single sendmsg call.
|
||||
// From net/scm.h.
|
||||
const SCM_MAX_FD = 253
|
||||
|
||||
// SO_ACCEPTCON is defined as __SO_ACCEPTCON in
|
||||
// include/uapi/linux/net.h, which represents a listening socket
|
||||
// state. Note that this is distinct from SO_ACCEPTCONN, which is a
|
||||
// socket option for querying whether a socket is in a listening
|
||||
// state.
|
||||
const SO_ACCEPTCON = 1 << 16
|
||||
|
||||
// ICMP6Filter represents struct icmp6_filter from linux/icmpv6.h.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type ICMP6Filter struct {
|
||||
Filter [8]uint32
|
||||
}
|
||||
|
||||
// Size of corresponding structs.
|
||||
var (
|
||||
ICMP6FilterSize = (*ICMP6Filter)(nil).SizeBytes()
|
||||
SockAddrInetSize = (*SockAddrInet)(nil).SizeBytes()
|
||||
SockAddrInet6Size = (*SockAddrInet6)(nil).SizeBytes()
|
||||
SockAddrLinkSize = (*SockAddrLink)(nil).SizeBytes()
|
||||
)
|
||||
23
pkg/abi/linux/splice.go
Normal file
23
pkg/abi/linux/splice.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Constants for splice(2), sendfile(2) and tee(2).
|
||||
const (
|
||||
SPLICE_F_MOVE = 1 << iota
|
||||
SPLICE_F_NONBLOCK
|
||||
SPLICE_F_MORE
|
||||
SPLICE_F_GIFT
|
||||
)
|
||||
71
pkg/abi/linux/tcp.go
Normal file
71
pkg/abi/linux/tcp.go
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Socket options from uapi/linux/tcp.h.
|
||||
const (
|
||||
TCP_NODELAY = 1
|
||||
TCP_MAXSEG = 2
|
||||
TCP_CORK = 3
|
||||
TCP_KEEPIDLE = 4
|
||||
TCP_KEEPINTVL = 5
|
||||
TCP_KEEPCNT = 6
|
||||
TCP_SYNCNT = 7
|
||||
TCP_LINGER2 = 8
|
||||
TCP_DEFER_ACCEPT = 9
|
||||
TCP_WINDOW_CLAMP = 10
|
||||
TCP_INFO = 11
|
||||
TCP_QUICKACK = 12
|
||||
TCP_CONGESTION = 13
|
||||
TCP_MD5SIG = 14
|
||||
TCP_THIN_LINEAR_TIMEOUTS = 16
|
||||
TCP_THIN_DUPACK = 17
|
||||
TCP_USER_TIMEOUT = 18
|
||||
TCP_REPAIR = 19
|
||||
TCP_REPAIR_QUEUE = 20
|
||||
TCP_QUEUE_SEQ = 21
|
||||
TCP_REPAIR_OPTIONS = 22
|
||||
TCP_FASTOPEN = 23
|
||||
TCP_TIMESTAMP = 24
|
||||
TCP_NOTSENT_LOWAT = 25
|
||||
TCP_CC_INFO = 26
|
||||
TCP_SAVE_SYN = 27
|
||||
TCP_SAVED_SYN = 28
|
||||
TCP_REPAIR_WINDOW = 29
|
||||
TCP_FASTOPEN_CONNECT = 30
|
||||
TCP_ULP = 31
|
||||
TCP_MD5SIG_EXT = 32
|
||||
TCP_FASTOPEN_KEY = 33
|
||||
TCP_FASTOPEN_NO_COOKIE = 34
|
||||
TCP_ZEROCOPY_RECEIVE = 35
|
||||
TCP_INQ = 36
|
||||
TCP_TX_DELAY = 37
|
||||
)
|
||||
|
||||
// Socket constants from include/net/tcp.h.
|
||||
const (
|
||||
MAX_TCP_KEEPIDLE = 32767
|
||||
MAX_TCP_KEEPINTVL = 32767
|
||||
MAX_TCP_KEEPCNT = 127
|
||||
)
|
||||
|
||||
// Congestion control states from include/uapi/linux/tcp.h.
|
||||
const (
|
||||
TCP_CA_Open = 0
|
||||
TCP_CA_Disorder = 1
|
||||
TCP_CA_CWR = 2
|
||||
TCP_CA_Recovery = 3
|
||||
TCP_CA_Loss = 4
|
||||
)
|
||||
288
pkg/abi/linux/time.go
Normal file
288
pkg/abi/linux/time.go
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// ClockTick is the length of time represented by a single clock tick, as
|
||||
// used by times(2) and /proc/[pid]/stat.
|
||||
ClockTick = time.Second / CLOCKS_PER_SEC
|
||||
|
||||
// CLOCKS_PER_SEC is the number of ClockTicks per second.
|
||||
//
|
||||
// Linux defines this to be 100 on most architectures, irrespective of
|
||||
// CONFIG_HZ. Userspace obtains the value through sysconf(_SC_CLK_TCK),
|
||||
// which uses the AT_CLKTCK entry in the auxiliary vector if one is
|
||||
// provided, and assumes 100 otherwise (glibc:
|
||||
// sysdeps/posix/sysconf.c:__sysconf() =>
|
||||
// sysdeps/unix/sysv/linux/getclktck.c, elf/dl-support.c:_dl_aux_init()).
|
||||
//
|
||||
// Not to be confused with POSIX CLOCKS_PER_SEC, as used by clock(3); "XSI
|
||||
// requires that [POSIX] CLOCKS_PER_SEC equals 1000000 independent of the
|
||||
// actual resolution" - clock(3).
|
||||
CLOCKS_PER_SEC = 100
|
||||
)
|
||||
|
||||
// CPU clock types for use with clock_gettime(2) et al.
|
||||
//
|
||||
// The 29 most significant bits of a 32 bit clock ID are either a PID or a FD.
|
||||
//
|
||||
// Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3.
|
||||
//
|
||||
// Bit 2 indicates whether a cpu clock refers to a thread or a process.
|
||||
const (
|
||||
CPUCLOCK_PROF = 0
|
||||
CPUCLOCK_VIRT = 1
|
||||
CPUCLOCK_SCHED = 2
|
||||
CPUCLOCK_MAX = 3
|
||||
CLOCKFD = CPUCLOCK_MAX
|
||||
|
||||
CPUCLOCK_CLOCK_MASK = 3
|
||||
CPUCLOCK_PERTHREAD_MASK = 4
|
||||
)
|
||||
|
||||
// Clock identifiers for use with clock_gettime(2), clock_getres(2),
|
||||
// clock_nanosleep(2).
|
||||
const (
|
||||
CLOCK_REALTIME = 0
|
||||
CLOCK_MONOTONIC = 1
|
||||
CLOCK_PROCESS_CPUTIME_ID = 2
|
||||
CLOCK_THREAD_CPUTIME_ID = 3
|
||||
CLOCK_MONOTONIC_RAW = 4
|
||||
CLOCK_REALTIME_COARSE = 5
|
||||
CLOCK_MONOTONIC_COARSE = 6
|
||||
CLOCK_BOOTTIME = 7
|
||||
CLOCK_REALTIME_ALARM = 8
|
||||
CLOCK_BOOTTIME_ALARM = 9
|
||||
)
|
||||
|
||||
// Flags for clock_nanosleep(2).
|
||||
const (
|
||||
TIMER_ABSTIME = 1
|
||||
)
|
||||
|
||||
// Flags for timerfd syscalls (timerfd_create(2), timerfd_settime(2)).
|
||||
const (
|
||||
// TFD_CLOEXEC is a timerfd_create flag.
|
||||
TFD_CLOEXEC = O_CLOEXEC
|
||||
|
||||
// TFD_NONBLOCK is a timerfd_create flag.
|
||||
TFD_NONBLOCK = O_NONBLOCK
|
||||
|
||||
// TFD_TIMER_ABSTIME is a timerfd_settime flag.
|
||||
TFD_TIMER_ABSTIME = 1
|
||||
)
|
||||
|
||||
// The safe number of seconds you can represent by int64.
|
||||
const maxSecInDuration = math.MaxInt64 / int64(time.Second)
|
||||
|
||||
// TimeT represents time_t in <time.h>. It represents time in seconds.
|
||||
//
|
||||
// +marshal
|
||||
type TimeT int64
|
||||
|
||||
// NsecToTimeT translates nanoseconds to TimeT (seconds).
|
||||
func NsecToTimeT(nsec int64) TimeT {
|
||||
return TimeT(nsec / 1e9)
|
||||
}
|
||||
|
||||
// Timespec represents struct timespec in <time.h>.
|
||||
//
|
||||
// +marshal slice:TimespecSlice
|
||||
type Timespec struct {
|
||||
Sec int64
|
||||
Nsec int64
|
||||
}
|
||||
|
||||
// Unix returns the second and nanosecond.
|
||||
func (ts Timespec) Unix() (sec int64, nsec int64) {
|
||||
return int64(ts.Sec), int64(ts.Nsec)
|
||||
}
|
||||
|
||||
// ToTime returns the Go time.Time representation.
|
||||
func (ts Timespec) ToTime() time.Time {
|
||||
return time.Unix(ts.Sec, ts.Nsec)
|
||||
}
|
||||
|
||||
// ToNsec returns the nanosecond representation.
|
||||
func (ts Timespec) ToNsec() int64 {
|
||||
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
|
||||
}
|
||||
|
||||
// ToNsecCapped returns the safe nanosecond representation.
|
||||
func (ts Timespec) ToNsecCapped() int64 {
|
||||
if ts.Sec > maxSecInDuration {
|
||||
return math.MaxInt64
|
||||
}
|
||||
return ts.ToNsec()
|
||||
}
|
||||
|
||||
// ToDuration returns the safe nanosecond representation as time.Duration.
|
||||
func (ts Timespec) ToDuration() time.Duration {
|
||||
return time.Duration(ts.ToNsecCapped())
|
||||
}
|
||||
|
||||
// Valid returns whether the timespec contains valid values.
|
||||
func (ts Timespec) Valid() bool {
|
||||
return !(ts.Sec < 0 || ts.Nsec < 0 || ts.Nsec >= int64(time.Second))
|
||||
}
|
||||
|
||||
// NsecToTimespec translates nanoseconds to Timespec.
|
||||
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||
ts.Sec = nsec / 1e9
|
||||
ts.Nsec = nsec % 1e9
|
||||
return
|
||||
}
|
||||
|
||||
// DurationToTimespec translates time.Duration to Timespec.
|
||||
func DurationToTimespec(dur time.Duration) Timespec {
|
||||
return NsecToTimespec(dur.Nanoseconds())
|
||||
}
|
||||
|
||||
// SizeOfTimeval is the size of a Timeval struct in bytes.
|
||||
const SizeOfTimeval = 16
|
||||
|
||||
// Timeval represents struct timeval in <time.h>.
|
||||
//
|
||||
// +marshal slice:TimevalSlice
|
||||
type Timeval struct {
|
||||
Sec int64
|
||||
Usec int64
|
||||
}
|
||||
|
||||
// ToNsecCapped returns the safe nanosecond representation.
|
||||
func (tv Timeval) ToNsecCapped() int64 {
|
||||
if tv.Sec > maxSecInDuration {
|
||||
return math.MaxInt64
|
||||
}
|
||||
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3
|
||||
}
|
||||
|
||||
// ToDuration returns the safe nanosecond representation as a time.Duration.
|
||||
func (tv Timeval) ToDuration() time.Duration {
|
||||
return time.Duration(tv.ToNsecCapped())
|
||||
}
|
||||
|
||||
// ToTime returns the Go time.Time representation.
|
||||
func (tv Timeval) ToTime() time.Time {
|
||||
return time.Unix(tv.Sec, tv.Usec*1e3)
|
||||
}
|
||||
|
||||
// NsecToTimeval translates nanosecond to Timeval.
|
||||
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Sec = nsec / 1e9
|
||||
tv.Usec = nsec % 1e9 / 1e3
|
||||
return
|
||||
}
|
||||
|
||||
// DurationToTimeval translates time.Duration to Timeval.
|
||||
func DurationToTimeval(dur time.Duration) Timeval {
|
||||
return NsecToTimeval(dur.Nanoseconds())
|
||||
}
|
||||
|
||||
// Itimerspec represents struct itimerspec in <time.h>.
|
||||
//
|
||||
// +marshal
|
||||
type Itimerspec struct {
|
||||
Interval Timespec
|
||||
Value Timespec
|
||||
}
|
||||
|
||||
// ItimerVal mimics the following struct in <sys/time.h>
|
||||
//
|
||||
// struct itimerval {
|
||||
// struct timeval it_interval; /* next value */
|
||||
// struct timeval it_value; /* current value */
|
||||
// };
|
||||
//
|
||||
// +marshal
|
||||
type ItimerVal struct {
|
||||
Interval Timeval
|
||||
Value Timeval
|
||||
}
|
||||
|
||||
// ClockT represents type clock_t.
|
||||
//
|
||||
// +marshal
|
||||
type ClockT int64
|
||||
|
||||
// ClockTFromDuration converts time.Duration to clock_t.
|
||||
func ClockTFromDuration(d time.Duration) ClockT {
|
||||
return ClockT(d / ClockTick)
|
||||
}
|
||||
|
||||
// Tms represents struct tms, used by times(2).
|
||||
//
|
||||
// +marshal
|
||||
type Tms struct {
|
||||
UTime ClockT
|
||||
STime ClockT
|
||||
CUTime ClockT
|
||||
CSTime ClockT
|
||||
}
|
||||
|
||||
// TimerID represents type timer_t, which identifies a POSIX per-process
|
||||
// interval timer.
|
||||
//
|
||||
// +marshal
|
||||
type TimerID int32
|
||||
|
||||
// StatxTimestamp represents struct statx_timestamp.
|
||||
//
|
||||
// +marshal
|
||||
type StatxTimestamp struct {
|
||||
Sec int64
|
||||
Nsec uint32
|
||||
_ int32
|
||||
}
|
||||
|
||||
// ToNsec returns the nanosecond representation.
|
||||
func (sxts StatxTimestamp) ToNsec() int64 {
|
||||
return int64(sxts.Sec)*1e9 + int64(sxts.Nsec)
|
||||
}
|
||||
|
||||
// ToNsecCapped returns the safe nanosecond representation.
|
||||
func (sxts StatxTimestamp) ToNsecCapped() int64 {
|
||||
if sxts.Sec > maxSecInDuration {
|
||||
return math.MaxInt64
|
||||
}
|
||||
return sxts.ToNsec()
|
||||
}
|
||||
|
||||
// NsecToStatxTimestamp translates nanoseconds to StatxTimestamp.
|
||||
func NsecToStatxTimestamp(nsec int64) (ts StatxTimestamp) {
|
||||
return StatxTimestamp{
|
||||
Sec: nsec / 1e9,
|
||||
Nsec: uint32(nsec % 1e9),
|
||||
}
|
||||
}
|
||||
|
||||
// ToTime returns the Go time.Time representation.
|
||||
func (sxts StatxTimestamp) ToTime() time.Time {
|
||||
return time.Unix(sxts.Sec, int64(sxts.Nsec))
|
||||
}
|
||||
|
||||
// Utime represents struct utimbuf used by utimes(2).
|
||||
//
|
||||
// +marshal
|
||||
type Utime struct {
|
||||
Actime int64
|
||||
Modtime int64
|
||||
}
|
||||
23
pkg/abi/linux/timer.go
Normal file
23
pkg/abi/linux/timer.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// itimer types for getitimer(2) and setitimer(2), from
|
||||
// include/uapi/linux/time.h.
|
||||
const (
|
||||
ITIMER_REAL = 0
|
||||
ITIMER_VIRTUAL = 1
|
||||
ITIMER_PROF = 2
|
||||
)
|
||||
349
pkg/abi/linux/tty.go
Normal file
349
pkg/abi/linux/tty.go
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
const (
|
||||
// NumControlCharacters is the number of control characters in Termios.
|
||||
NumControlCharacters = 19
|
||||
// disabledChar is used to indicate that a control character is
|
||||
// disabled.
|
||||
disabledChar = 0
|
||||
)
|
||||
|
||||
// Winsize is struct winsize, defined in uapi/asm-generic/termios.h.
|
||||
//
|
||||
// +marshal
|
||||
type Winsize struct {
|
||||
Row uint16
|
||||
Col uint16
|
||||
Xpixel uint16
|
||||
Ypixel uint16
|
||||
}
|
||||
|
||||
// Termios is struct termios, defined in uapi/asm-generic/termbits.h.
|
||||
//
|
||||
// +marshal
|
||||
type Termios struct {
|
||||
InputFlags uint32
|
||||
OutputFlags uint32
|
||||
ControlFlags uint32
|
||||
LocalFlags uint32
|
||||
LineDiscipline uint8
|
||||
ControlCharacters [NumControlCharacters]uint8
|
||||
}
|
||||
|
||||
// KernelTermios is struct ktermios/struct termios2, defined in
|
||||
// uapi/asm-generic/termbits.h.
|
||||
//
|
||||
// +stateify savable
|
||||
type KernelTermios struct {
|
||||
InputFlags uint32
|
||||
OutputFlags uint32
|
||||
ControlFlags uint32
|
||||
LocalFlags uint32
|
||||
LineDiscipline uint8
|
||||
ControlCharacters [NumControlCharacters]uint8
|
||||
InputSpeed uint32
|
||||
OutputSpeed uint32
|
||||
}
|
||||
|
||||
// IEnabled returns whether flag is enabled in termios input flags.
|
||||
func (t *KernelTermios) IEnabled(flag uint32) bool {
|
||||
return t.InputFlags&flag == flag
|
||||
}
|
||||
|
||||
// OEnabled returns whether flag is enabled in termios output flags.
|
||||
func (t *KernelTermios) OEnabled(flag uint32) bool {
|
||||
return t.OutputFlags&flag == flag
|
||||
}
|
||||
|
||||
// CEnabled returns whether flag is enabled in termios control flags.
|
||||
func (t *KernelTermios) CEnabled(flag uint32) bool {
|
||||
return t.ControlFlags&flag == flag
|
||||
}
|
||||
|
||||
// LEnabled returns whether flag is enabled in termios local flags.
|
||||
func (t *KernelTermios) LEnabled(flag uint32) bool {
|
||||
return t.LocalFlags&flag == flag
|
||||
}
|
||||
|
||||
// ToTermios copies fields that are shared with Termios into a new Termios
|
||||
// struct.
|
||||
func (t *KernelTermios) ToTermios() Termios {
|
||||
return Termios{
|
||||
InputFlags: t.InputFlags,
|
||||
OutputFlags: t.OutputFlags,
|
||||
ControlFlags: t.ControlFlags,
|
||||
LocalFlags: t.LocalFlags,
|
||||
LineDiscipline: t.LineDiscipline,
|
||||
ControlCharacters: t.ControlCharacters,
|
||||
}
|
||||
}
|
||||
|
||||
// FromTermios copies fields that are shared with Termios into this
|
||||
// KernelTermios struct.
|
||||
func (t *KernelTermios) FromTermios(term Termios) {
|
||||
t.InputFlags = term.InputFlags
|
||||
t.OutputFlags = term.OutputFlags
|
||||
t.ControlFlags = term.ControlFlags
|
||||
t.LocalFlags = term.LocalFlags
|
||||
t.LineDiscipline = term.LineDiscipline
|
||||
t.ControlCharacters = term.ControlCharacters
|
||||
}
|
||||
|
||||
// IsTerminating returns whether c is a line terminating character.
|
||||
func (t *KernelTermios) IsTerminating(cBytes []byte) bool {
|
||||
// All terminating characters are 1 byte.
|
||||
if len(cBytes) != 1 {
|
||||
return false
|
||||
}
|
||||
c := cBytes[0]
|
||||
|
||||
// Is this the user-set EOF character?
|
||||
if t.IsEOF(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
switch c {
|
||||
case disabledChar:
|
||||
return false
|
||||
case '\n', t.ControlCharacters[VEOL]:
|
||||
return true
|
||||
case t.ControlCharacters[VEOL2]:
|
||||
return t.LEnabled(IEXTEN)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsEOF returns whether c is the EOF character.
|
||||
func (t *KernelTermios) IsEOF(c byte) bool {
|
||||
return c == t.ControlCharacters[VEOF] && t.ControlCharacters[VEOF] != disabledChar
|
||||
}
|
||||
|
||||
// Input flags.
|
||||
const (
|
||||
IGNBRK = 0o000001
|
||||
BRKINT = 0o000002
|
||||
IGNPAR = 0o000004
|
||||
PARMRK = 0o000010
|
||||
INPCK = 0o000020
|
||||
ISTRIP = 0o000040
|
||||
INLCR = 0o000100
|
||||
IGNCR = 0o000200
|
||||
ICRNL = 0o000400
|
||||
IUCLC = 0o001000
|
||||
IXON = 0o002000
|
||||
IXANY = 0o004000
|
||||
IXOFF = 0o010000
|
||||
IMAXBEL = 0o020000
|
||||
IUTF8 = 0o040000
|
||||
)
|
||||
|
||||
// Output flags.
|
||||
const (
|
||||
OPOST = 0o000001
|
||||
OLCUC = 0o000002
|
||||
ONLCR = 0o000004
|
||||
OCRNL = 0o000010
|
||||
ONOCR = 0o000020
|
||||
ONLRET = 0o000040
|
||||
OFILL = 0o000100
|
||||
OFDEL = 0o000200
|
||||
NLDLY = 0o000400
|
||||
NL0 = 0o000000
|
||||
NL1 = 0o000400
|
||||
CRDLY = 0o003000
|
||||
CR0 = 0o000000
|
||||
CR1 = 0o001000
|
||||
CR2 = 0o002000
|
||||
CR3 = 0o003000
|
||||
TABDLY = 0o014000
|
||||
TAB0 = 0o000000
|
||||
TAB1 = 0o004000
|
||||
TAB2 = 0o010000
|
||||
TAB3 = 0o014000
|
||||
XTABS = 0o014000
|
||||
BSDLY = 0o020000
|
||||
BS0 = 0o000000
|
||||
BS1 = 0o020000
|
||||
VTDLY = 0o040000
|
||||
VT0 = 0o000000
|
||||
VT1 = 0o040000
|
||||
FFDLY = 0o100000
|
||||
FF0 = 0o000000
|
||||
FF1 = 0o100000
|
||||
)
|
||||
|
||||
// Control flags.
|
||||
const (
|
||||
CBAUD = 0o010017
|
||||
B0 = 0o000000
|
||||
B50 = 0o000001
|
||||
B75 = 0o000002
|
||||
B110 = 0o000003
|
||||
B134 = 0o000004
|
||||
B150 = 0o000005
|
||||
B200 = 0o000006
|
||||
B300 = 0o000007
|
||||
B600 = 0o000010
|
||||
B1200 = 0o000011
|
||||
B1800 = 0o000012
|
||||
B2400 = 0o000013
|
||||
B4800 = 0o000014
|
||||
B9600 = 0o000015
|
||||
B19200 = 0o000016
|
||||
B38400 = 0o000017
|
||||
EXTA = B19200
|
||||
EXTB = B38400
|
||||
CSIZE = 0o000060
|
||||
CS5 = 0o000000
|
||||
CS6 = 0o000020
|
||||
CS7 = 0o000040
|
||||
CS8 = 0o000060
|
||||
CSTOPB = 0o000100
|
||||
CREAD = 0o000200
|
||||
PARENB = 0o000400
|
||||
PARODD = 0o001000
|
||||
HUPCL = 0o002000
|
||||
CLOCAL = 0o004000
|
||||
CBAUDEX = 0o010000
|
||||
BOTHER = 0o010000
|
||||
B57600 = 0o010001
|
||||
B115200 = 0o010002
|
||||
B230400 = 0o010003
|
||||
B460800 = 0o010004
|
||||
B500000 = 0o010005
|
||||
B576000 = 0o010006
|
||||
B921600 = 0o010007
|
||||
B1000000 = 0o010010
|
||||
B1152000 = 0o010011
|
||||
B1500000 = 0o010012
|
||||
B2000000 = 0o010013
|
||||
B2500000 = 0o010014
|
||||
B3000000 = 0o010015
|
||||
B3500000 = 0o010016
|
||||
B4000000 = 0o010017
|
||||
CIBAUD = 0o02003600000
|
||||
CMSPAR = 0o10000000000
|
||||
CRTSCTS = 0o20000000000
|
||||
|
||||
// IBSHIFT is the shift from CBAUD to CIBAUD.
|
||||
IBSHIFT = 16
|
||||
)
|
||||
|
||||
// Local flags.
|
||||
const (
|
||||
ISIG = 0o000001
|
||||
ICANON = 0o000002
|
||||
XCASE = 0o000004
|
||||
ECHO = 0o000010
|
||||
ECHOE = 0o000020
|
||||
ECHOK = 0o000040
|
||||
ECHONL = 0o000100
|
||||
NOFLSH = 0o000200
|
||||
TOSTOP = 0o000400
|
||||
ECHOCTL = 0o001000
|
||||
ECHOPRT = 0o002000
|
||||
ECHOKE = 0o004000
|
||||
FLUSHO = 0o010000
|
||||
PENDIN = 0o040000
|
||||
IEXTEN = 0o100000
|
||||
EXTPROC = 0o200000
|
||||
)
|
||||
|
||||
// Control Character indices.
|
||||
const (
|
||||
VINTR = 0
|
||||
VQUIT = 1
|
||||
VERASE = 2
|
||||
VKILL = 3
|
||||
VEOF = 4
|
||||
VTIME = 5
|
||||
VMIN = 6
|
||||
VSWTC = 7
|
||||
VSTART = 8
|
||||
VSTOP = 9
|
||||
VSUSP = 10
|
||||
VEOL = 11
|
||||
VREPRINT = 12
|
||||
VDISCARD = 13
|
||||
VWERASE = 14
|
||||
VLNEXT = 15
|
||||
VEOL2 = 16
|
||||
)
|
||||
|
||||
// ControlCharacter returns the termios-style control character for the passed
|
||||
// character.
|
||||
//
|
||||
// e.g., for Ctrl-C, i.e., ^C, call ControlCharacter('C').
|
||||
//
|
||||
// Standard control characters are ASCII bytes 0 through 31.
|
||||
func ControlCharacter(c byte) uint8 {
|
||||
// A is 1, B is 2, etc.
|
||||
return uint8(c - 'A' + 1)
|
||||
}
|
||||
|
||||
// DefaultControlCharacters is the default set of Termios control characters.
|
||||
var DefaultControlCharacters = [NumControlCharacters]uint8{
|
||||
ControlCharacter('C'), // VINTR = ^C
|
||||
ControlCharacter('\\'), // VQUIT = ^\
|
||||
'\x7f', // VERASE = DEL
|
||||
ControlCharacter('U'), // VKILL = ^U
|
||||
ControlCharacter('D'), // VEOF = ^D
|
||||
0, // VTIME
|
||||
1, // VMIN
|
||||
0, // VSWTC
|
||||
ControlCharacter('Q'), // VSTART = ^Q
|
||||
ControlCharacter('S'), // VSTOP = ^S
|
||||
ControlCharacter('Z'), // VSUSP = ^Z
|
||||
0, // VEOL
|
||||
ControlCharacter('R'), // VREPRINT = ^R
|
||||
ControlCharacter('O'), // VDISCARD = ^O
|
||||
ControlCharacter('W'), // VWERASE = ^W
|
||||
ControlCharacter('V'), // VLNEXT = ^V
|
||||
0, // VEOL2
|
||||
}
|
||||
|
||||
// MasterTermios is the terminal configuration of the master end of a Unix98
|
||||
// pseudoterminal.
|
||||
var MasterTermios = KernelTermios{
|
||||
ControlFlags: B38400 | CS8 | CREAD,
|
||||
ControlCharacters: DefaultControlCharacters,
|
||||
InputSpeed: 38400,
|
||||
OutputSpeed: 38400,
|
||||
}
|
||||
|
||||
// DefaultReplicaTermios is the default terminal configuration of the replica
|
||||
// end of a Unix98 pseudoterminal.
|
||||
var DefaultReplicaTermios = KernelTermios{
|
||||
InputFlags: ICRNL | IXON,
|
||||
OutputFlags: OPOST | ONLCR,
|
||||
ControlFlags: B38400 | CS8 | CREAD,
|
||||
LocalFlags: ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN,
|
||||
ControlCharacters: DefaultControlCharacters,
|
||||
InputSpeed: 38400,
|
||||
OutputSpeed: 38400,
|
||||
}
|
||||
|
||||
// WindowSize corresponds to struct winsize defined in
|
||||
// include/uapi/asm-generic/termios.h.
|
||||
//
|
||||
// +stateify savable
|
||||
// +marshal
|
||||
type WindowSize struct {
|
||||
Rows uint16
|
||||
Cols uint16
|
||||
_ [4]byte // Padding for 2 unused shorts.
|
||||
}
|
||||
18
pkg/abi/linux/uio.go
Normal file
18
pkg/abi/linux/uio.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// UIO_MAXIOV is the maximum number of struct iovecs in a struct iovec array.
|
||||
const UIO_MAXIOV = 1024
|
||||
51
pkg/abi/linux/utsname.go
Normal file
51
pkg/abi/linux/utsname.go
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
// UTSLen is the maximum length of strings contained in fields of
|
||||
// UtsName.
|
||||
UTSLen = 64
|
||||
)
|
||||
|
||||
// UtsName represents struct utsname, the struct returned by uname(2).
|
||||
//
|
||||
// +marshal
|
||||
type UtsName struct {
|
||||
Sysname [UTSLen + 1]byte
|
||||
Nodename [UTSLen + 1]byte
|
||||
Release [UTSLen + 1]byte
|
||||
Version [UTSLen + 1]byte
|
||||
Machine [UTSLen + 1]byte
|
||||
Domainname [UTSLen + 1]byte
|
||||
}
|
||||
|
||||
// utsNameString converts a UtsName entry to a string without NULs.
|
||||
func utsNameString(s [UTSLen + 1]byte) string {
|
||||
// The NUL bytes will remain even in a cast to string. We must
|
||||
// explicitly strip them.
|
||||
return string(bytes.TrimRight(s[:], "\x00"))
|
||||
}
|
||||
|
||||
func (u UtsName) String() string {
|
||||
return fmt.Sprintf("{Sysname: %s, Nodename: %s, Release: %s, Version: %s, Machine: %s, Domainname: %s}",
|
||||
utsNameString(u.Sysname), utsNameString(u.Nodename), utsNameString(u.Release),
|
||||
utsNameString(u.Version), utsNameString(u.Machine), utsNameString(u.Domainname))
|
||||
}
|
||||
215
pkg/abi/linux/vfio.go
Normal file
215
pkg/abi/linux/vfio.go
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
// Copyright 2024 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The package implements VFIOuserspace driver interface.
|
||||
|
||||
package linux
|
||||
|
||||
// For IOCTLs requests from include/uapi/linux/vfio.h.
|
||||
const (
|
||||
VFIO_TYPE = ';'
|
||||
VFIO_BASE = 100
|
||||
|
||||
// VFIO extensions.
|
||||
VFIO_TYPE1_IOMMU = 1
|
||||
VFIO_SPAPR_TCE_IOMMU = 2
|
||||
VFIO_TYPE1v2_IOMMU = 3
|
||||
)
|
||||
|
||||
// VFIO device info flags.
|
||||
const (
|
||||
// Device supports reset.
|
||||
VFIO_DEVICE_FLAGS_RESET = 1 << iota
|
||||
// VFIO-pci device.
|
||||
VFIO_DEVICE_FLAGS_PCI
|
||||
// VFIO-platform device.
|
||||
VFIO_DEVICE_FLAGS_PLATFORM
|
||||
// VFIO-amba device.
|
||||
VFIO_DEVICE_FLAGS_AMBA
|
||||
// VFIO-ccw device.
|
||||
VFIO_DEVICE_FLAGS_CCW
|
||||
// VFIO-ap device.
|
||||
VFIO_DEVICE_FLAGS_AP
|
||||
// VFIO-fsl-mc device.
|
||||
VFIO_DEVICE_FLAGS_FSL_MC
|
||||
// Info supports caps.
|
||||
VFIO_DEVICE_FLAGS_CAPS
|
||||
// VFIO-cdx device.
|
||||
VFIO_DEVICE_FLAGS_CDX
|
||||
)
|
||||
|
||||
// VFIO region info flags.
|
||||
const (
|
||||
// Region supports read.
|
||||
VFIO_REGION_INFO_FLAG_READ = 1 << iota
|
||||
// Region supports write.
|
||||
VFIO_REGION_INFO_FLAG_WRITE
|
||||
// Region supports mmap.
|
||||
VFIO_REGION_INFO_FLAG_MMAP
|
||||
// Info supports caps.
|
||||
VFIO_REGION_INFO_FLAG_CAPS
|
||||
)
|
||||
|
||||
// VFIOIrqInfo flags.
|
||||
const (
|
||||
VFIO_IRQ_INFO_EVENTFD = 1 << iota
|
||||
VFIO_IRQ_INFO_MASKABLE
|
||||
VFIO_IRQ_INFO_AUTOMASKED
|
||||
VFIO_IRQ_INFO_NORESIZE
|
||||
)
|
||||
|
||||
// VFIOIrqSet flags.
|
||||
const (
|
||||
VFIO_IRQ_SET_DATA_NONE = 1 << iota
|
||||
VFIO_IRQ_SET_DATA_BOOL
|
||||
VFIO_IRQ_SET_DATA_EVENTFD
|
||||
VFIO_IRQ_SET_ACTION_MASK
|
||||
VFIO_IRQ_SET_ACTION_UNMASK
|
||||
VFIO_IRQ_SET_ACTION_TRIGGER
|
||||
|
||||
VFIO_IRQ_SET_DATA_TYPE_MASK = VFIO_IRQ_SET_DATA_NONE |
|
||||
VFIO_IRQ_SET_DATA_BOOL |
|
||||
VFIO_IRQ_SET_DATA_EVENTFD
|
||||
VFIO_IRQ_SET_ACTION_TYPE_MASK = VFIO_IRQ_SET_ACTION_MASK |
|
||||
VFIO_IRQ_SET_ACTION_UNMASK |
|
||||
VFIO_IRQ_SET_ACTION_TRIGGER
|
||||
)
|
||||
|
||||
// VFIOIrqSet index.
|
||||
const (
|
||||
VFIO_PCI_INTX_IRQ_INDEX = iota
|
||||
VFIO_PCI_MSI_IRQ_INDEX
|
||||
VFIO_PCI_MSIX_IRQ_INDEX
|
||||
VFIO_PCI_ERR_IRQ_INDEX
|
||||
VFIO_PCI_REQ_IRQ_INDEX
|
||||
VFIO_PCI_NUM_IRQS
|
||||
)
|
||||
|
||||
// VFIOIommuType1DmaMap flags.
|
||||
const (
|
||||
// Readable from device.
|
||||
VFIO_DMA_MAP_FLAG_READ = 1 << iota
|
||||
// Writable from device.
|
||||
VFIO_DMA_MAP_FLAG_WRITE
|
||||
// Update the device's virtual address.
|
||||
VFIO_DMA_MAP_FLAG_VADDR
|
||||
)
|
||||
|
||||
const (
|
||||
VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP = 1
|
||||
)
|
||||
|
||||
// IOCTLs for VFIO file descriptor from include/uapi/linux/vfio.h.
|
||||
var (
|
||||
VFIO_CHECK_EXTENSION = IO(VFIO_TYPE, VFIO_BASE+1)
|
||||
VFIO_SET_IOMMU = IO(VFIO_TYPE, VFIO_BASE+2)
|
||||
VFIO_GROUP_SET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+4)
|
||||
VFIO_GROUP_UNSET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+5)
|
||||
VFIO_GROUP_GET_DEVICE_FD = IO(VFIO_TYPE, VFIO_BASE+6)
|
||||
VFIO_DEVICE_GET_INFO = IO(VFIO_TYPE, VFIO_BASE+7)
|
||||
VFIO_DEVICE_GET_REGION_INFO = IO(VFIO_TYPE, VFIO_BASE+8)
|
||||
VFIO_DEVICE_GET_IRQ_INFO = IO(VFIO_TYPE, VFIO_BASE+9)
|
||||
VFIO_DEVICE_SET_IRQS = IO(VFIO_TYPE, VFIO_BASE+10)
|
||||
VFIO_DEVICE_RESET = IO(VFIO_TYPE, VFIO_BASE+11)
|
||||
VFIO_IOMMU_MAP_DMA = IO(VFIO_TYPE, VFIO_BASE+13)
|
||||
VFIO_IOMMU_UNMAP_DMA = IO(VFIO_TYPE, VFIO_BASE+14)
|
||||
)
|
||||
|
||||
// VFIODeviceInfo is analogous to vfio_device_info
|
||||
// from include/uapi/linux/vfio.h.
|
||||
//
|
||||
// +marshal
|
||||
type VFIODeviceInfo struct {
|
||||
Argsz uint32
|
||||
Flags uint32
|
||||
// The total amount of regions.
|
||||
NumRegions uint32
|
||||
// The maximum number of IRQ.
|
||||
NumIrqs uint32
|
||||
// Offset within info struct of first cap.
|
||||
CapOffset uint32
|
||||
pad uint32
|
||||
}
|
||||
|
||||
// VFIORegionInfo is analogous to vfio_region_info
|
||||
// from include/uapi/linux/vfio.h.
|
||||
//
|
||||
// +marshal
|
||||
type VFIORegionInfo struct {
|
||||
Argsz uint32
|
||||
Flags uint32
|
||||
Index uint32
|
||||
// Offset within info struct of first cap.
|
||||
capOffset uint32
|
||||
// Region size in bytes.
|
||||
Size uint64
|
||||
// Region offset from start of device fd.
|
||||
Offset uint64
|
||||
}
|
||||
|
||||
// VFIOIrqInfo is analogous to vfio_irq_info
|
||||
// from include/uapi/linux/vfio.h.
|
||||
//
|
||||
// +marshal
|
||||
type VFIOIrqInfo struct {
|
||||
Argsz uint32
|
||||
Flags uint32
|
||||
Index uint32
|
||||
Count uint32
|
||||
}
|
||||
|
||||
// VFIOIrqSet is analogous to vfio_irq_set
|
||||
// from include/uapi/linux/vfio.h.
|
||||
// The last field `data` from vfio_irq_set is omitted which is an
|
||||
// flexible array member. It will be handled separately.
|
||||
//
|
||||
// +marshal
|
||||
type VFIOIrqSet struct {
|
||||
Argsz uint32
|
||||
Flags uint32
|
||||
Index uint32
|
||||
Start uint32
|
||||
Count uint32
|
||||
}
|
||||
|
||||
// VFIOIommuType1DmaMap is analogous to vfio_iommu_type1_dma_map
|
||||
// from include/uapi/linux/vfio.h.
|
||||
//
|
||||
// +marshal
|
||||
type VFIOIommuType1DmaMap struct {
|
||||
Argsz uint32
|
||||
Flags uint32
|
||||
// Process virtual address.
|
||||
Vaddr uint64
|
||||
// IO virtual address.
|
||||
IOVa uint64
|
||||
// Size of mapping in bytes.
|
||||
Size uint64
|
||||
}
|
||||
|
||||
// VFIOIommuType1DmaUnmap is analogous to vfio_iommu_type1_dma_unmap
|
||||
// from include/uapi/linux/vfio.h.
|
||||
//
|
||||
// +marshal
|
||||
type VFIOIommuType1DmaUnmap struct {
|
||||
Argsz uint32
|
||||
Flags uint32
|
||||
// IO virtual address.
|
||||
IOVa uint64
|
||||
// Size of mapping in bytes.
|
||||
Size uint64
|
||||
// The `data` field from vfio_iommu_type1_dma_unmap is omitted. The
|
||||
// field is a flexible array member, and is needed only if the flag
|
||||
// VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP is enabled.
|
||||
}
|
||||
22
pkg/abi/linux/vfio_unsafe.go
Normal file
22
pkg/abi/linux/vfio_unsafe.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2024 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Size returns the number of bytes for a VFIOIrqSet object.
|
||||
func (vfioIrqSet VFIOIrqSet) Size() uint64 {
|
||||
return uint64(unsafe.Sizeof(vfioIrqSet))
|
||||
}
|
||||
161
pkg/abi/linux/wait.go
Normal file
161
pkg/abi/linux/wait.go
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Options for waitpid(2), wait4(2), and/or waitid(2), from
|
||||
// include/uapi/linux/wait.h.
|
||||
const (
|
||||
WNOHANG = 0x00000001
|
||||
WUNTRACED = 0x00000002
|
||||
WSTOPPED = WUNTRACED
|
||||
WEXITED = 0x00000004
|
||||
WCONTINUED = 0x00000008
|
||||
WNOWAIT = 0x01000000
|
||||
WNOTHREAD = 0x20000000
|
||||
WALL = 0x40000000
|
||||
WCLONE = 0x80000000
|
||||
)
|
||||
|
||||
// ID types for waitid(2), from include/uapi/linux/wait.h.
|
||||
const (
|
||||
P_ALL = 0x0
|
||||
P_PID = 0x1
|
||||
P_PGID = 0x2
|
||||
)
|
||||
|
||||
// WaitStatus represents a thread status, as returned by the wait* family of
|
||||
// syscalls.
|
||||
type WaitStatus uint32
|
||||
|
||||
// WaitStatusExit returns a WaitStatus representing the given exit status.
|
||||
func WaitStatusExit(status int32) WaitStatus {
|
||||
return WaitStatus(uint32(status) << 8)
|
||||
}
|
||||
|
||||
// WaitStatusTerminationSignal returns a WaitStatus representing termination by
|
||||
// the given signal.
|
||||
func WaitStatusTerminationSignal(sig Signal) WaitStatus {
|
||||
return WaitStatus(uint32(sig))
|
||||
}
|
||||
|
||||
// WaitStatusStopped returns a WaitStatus representing stoppage by the given
|
||||
// signal or ptrace trap code.
|
||||
func WaitStatusStopped(code uint32) WaitStatus {
|
||||
return WaitStatus(code<<8 | 0x7f)
|
||||
}
|
||||
|
||||
// WaitStatusContinued returns a WaitStatus representing continuation by
|
||||
// SIGCONT.
|
||||
func WaitStatusContinued() WaitStatus {
|
||||
return WaitStatus(0xffff)
|
||||
}
|
||||
|
||||
// WithCoreDump returns a copy of ws that indicates that a core dump was
|
||||
// generated.
|
||||
//
|
||||
// Preconditions: ws.Signaled().
|
||||
func (ws WaitStatus) WithCoreDump() WaitStatus {
|
||||
return ws | 0x80
|
||||
}
|
||||
|
||||
// Exited returns true if ws represents an exit status, consistent with
|
||||
// WIFEXITED.
|
||||
func (ws WaitStatus) Exited() bool {
|
||||
return ws&0x7f == 0
|
||||
}
|
||||
|
||||
// Signaled returns true if ws represents a termination by signal, consistent
|
||||
// with WIFSIGNALED.
|
||||
func (ws WaitStatus) Signaled() bool {
|
||||
// ws&0x7f != 0 (exited) and ws&0x7f != 0x7f (stopped or continued)
|
||||
return ((ws&0x7f)+1)>>1 != 0
|
||||
}
|
||||
|
||||
// CoreDumped returns true if ws indicates that a core dump was produced,
|
||||
// consistent with WCOREDUMP.
|
||||
//
|
||||
// Preconditions: ws.Signaled().
|
||||
func (ws WaitStatus) CoreDumped() bool {
|
||||
return ws&0x80 != 0
|
||||
}
|
||||
|
||||
// Stopped returns true if ws represents a stoppage, consistent with
|
||||
// WIFSTOPPED.
|
||||
func (ws WaitStatus) Stopped() bool {
|
||||
return ws&0xff == 0x7f
|
||||
}
|
||||
|
||||
// Continued returns true if ws represents a continuation by SIGCONT,
|
||||
// consistent with WIFCONTINUED.
|
||||
func (ws WaitStatus) Continued() bool {
|
||||
return ws == 0xffff
|
||||
}
|
||||
|
||||
// ExitStatus returns the lower 8 bits of the exit status represented by ws,
|
||||
// consistent with WEXITSTATUS.
|
||||
//
|
||||
// Preconditions: ws.Exited().
|
||||
func (ws WaitStatus) ExitStatus() uint32 {
|
||||
return uint32((ws & 0xff00) >> 8)
|
||||
}
|
||||
|
||||
// TerminationSignal returns the termination signal represented by ws,
|
||||
// consistent with WTERMSIG.
|
||||
//
|
||||
// Preconditions: ws.Signaled().
|
||||
func (ws WaitStatus) TerminationSignal() Signal {
|
||||
return Signal(ws & 0x7f)
|
||||
}
|
||||
|
||||
// StopSignal returns the stop signal represented by ws, consistent with
|
||||
// WSTOPSIG.
|
||||
//
|
||||
// Preconditions: ws.Stopped().
|
||||
func (ws WaitStatus) StopSignal() Signal {
|
||||
return Signal((ws & 0xff00) >> 8)
|
||||
}
|
||||
|
||||
// PtraceEvent returns the PTRACE_EVENT_* field in ws.
|
||||
//
|
||||
// Preconditions: ws.Stopped().
|
||||
func (ws WaitStatus) PtraceEvent() uint32 {
|
||||
return uint32(ws >> 16)
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.String.
|
||||
func (ws WaitStatus) String() string {
|
||||
switch {
|
||||
case ws.Exited():
|
||||
return fmt.Sprintf("exit status %d", ws.ExitStatus())
|
||||
case ws.Signaled():
|
||||
if ws.CoreDumped() {
|
||||
return fmt.Sprintf("killed by signal %d (core dumped)", ws.TerminationSignal())
|
||||
}
|
||||
return fmt.Sprintf("killed by signal %d", ws.TerminationSignal())
|
||||
case ws.Stopped():
|
||||
if ev := ws.PtraceEvent(); ev != 0 {
|
||||
return fmt.Sprintf("stopped by signal %d (PTRACE_EVENT %d)", ws.StopSignal(), ev)
|
||||
}
|
||||
return fmt.Sprintf("stopped by signal %d", ws.StopSignal())
|
||||
case ws.Continued():
|
||||
return "continued"
|
||||
default:
|
||||
return fmt.Sprintf("unknown status %#x", uint32(ws))
|
||||
}
|
||||
}
|
||||
39
pkg/abi/linux/xattr.go
Normal file
39
pkg/abi/linux/xattr.go
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package linux
|
||||
|
||||
// Constants for extended attributes.
|
||||
const (
|
||||
XATTR_NAME_MAX = 255
|
||||
XATTR_SIZE_MAX = 65536
|
||||
XATTR_LIST_MAX = 65536
|
||||
|
||||
XATTR_CREATE = 1
|
||||
XATTR_REPLACE = 2
|
||||
|
||||
XATTR_SECURITY_PREFIX = "security."
|
||||
XATTR_SECURITY_PREFIX_LEN = len(XATTR_SECURITY_PREFIX)
|
||||
|
||||
XATTR_SECURITY_CAPABILITY = XATTR_SECURITY_PREFIX + "capability"
|
||||
|
||||
XATTR_SYSTEM_PREFIX = "system."
|
||||
XATTR_SYSTEM_PREFIX_LEN = len(XATTR_SYSTEM_PREFIX)
|
||||
|
||||
XATTR_TRUSTED_PREFIX = "trusted."
|
||||
XATTR_TRUSTED_PREFIX_LEN = len(XATTR_TRUSTED_PREFIX)
|
||||
|
||||
XATTR_USER_PREFIX = "user."
|
||||
XATTR_USER_PREFIX_LEN = len(XATTR_USER_PREFIX)
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue