summaryrefslogtreecommitdiffhomepage
path: root/pkg/abi/linux
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-07-23 18:48:01 +0000
committergVisor bot <gvisor-bot@google.com>2020-07-23 18:48:01 +0000
commit00d5db431685844b0d4492b24b003375381e14f3 (patch)
treeacc2779bceea6c80dbf4ca1355ce9fdcffc0b603 /pkg/abi/linux
parentfe1eac7e70817d61853f4469000f2dd6e19bdc52 (diff)
parent6f7f73996791bbab6b63c248000df0d3ce652f2b (diff)
Merge release-20200622.1-195-g6f7f73996 (automated)
Diffstat (limited to 'pkg/abi/linux')
-rw-r--r--pkg/abi/linux/linux_abi_autogen_unsafe.go1373
-rw-r--r--pkg/abi/linux/netfilter.go146
-rw-r--r--pkg/abi/linux/socket.go8
3 files changed, 1512 insertions, 15 deletions
diff --git a/pkg/abi/linux/linux_abi_autogen_unsafe.go b/pkg/abi/linux/linux_abi_autogen_unsafe.go
index 180c2a910..93a9932ab 100644
--- a/pkg/abi/linux/linux_abi_autogen_unsafe.go
+++ b/pkg/abi/linux/linux_abi_autogen_unsafe.go
@@ -14,15 +14,25 @@ import (
)
// Marshallable types used by this file.
+var _ marshal.Marshallable = (*ControlMessageCredentials)(nil)
+var _ marshal.Marshallable = (*IPTEntry)(nil)
+var _ marshal.Marshallable = (*IPTGetEntries)(nil)
+var _ marshal.Marshallable = (*IPTGetinfo)(nil)
+var _ marshal.Marshallable = (*IPTIP)(nil)
+var _ marshal.Marshallable = (*InetAddr)(nil)
+var _ marshal.Marshallable = (*Linger)(nil)
var _ marshal.Marshallable = (*NumaPolicy)(nil)
var _ marshal.Marshallable = (*RSeqCriticalSection)(nil)
var _ marshal.Marshallable = (*SignalSet)(nil)
var _ marshal.Marshallable = (*Statfs)(nil)
var _ marshal.Marshallable = (*Statx)(nil)
var _ marshal.Marshallable = (*StatxTimestamp)(nil)
+var _ marshal.Marshallable = (*TCPInfo)(nil)
+var _ marshal.Marshallable = (*TableName)(nil)
var _ marshal.Marshallable = (*Timespec)(nil)
var _ marshal.Marshallable = (*Timeval)(nil)
var _ marshal.Marshallable = (*Utime)(nil)
+var _ marshal.Marshallable = (*XTCounters)(nil)
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (s *Statx) SizeBytes() int {
@@ -129,7 +139,7 @@ func (s *Statx) Packed() bool {
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
func (s *Statx) MarshalUnsafe(dst []byte) {
- if s.Mtime.Packed() && s.Atime.Packed() && s.Btime.Packed() && s.Ctime.Packed() {
+ if s.Atime.Packed() && s.Btime.Packed() && s.Ctime.Packed() && s.Mtime.Packed() {
safecopy.CopyIn(dst, unsafe.Pointer(s))
} else {
s.MarshalBytes(dst)
@@ -148,7 +158,7 @@ func (s *Statx) UnmarshalUnsafe(src []byte) {
// CopyOutN implements marshal.Marshallable.CopyOutN.
//go:nosplit
func (s *Statx) CopyOutN(task marshal.Task, addr usermem.Addr, limit int) (int, error) {
- if !s.Btime.Packed() && s.Ctime.Packed() && s.Mtime.Packed() && s.Atime.Packed() {
+ if !s.Atime.Packed() && s.Btime.Packed() && s.Ctime.Packed() && s.Mtime.Packed() {
// Type Statx doesn't have a packed layout in memory, fall back to MarshalBytes.
buf := task.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
s.MarshalBytes(buf) // escapes: fallback.
@@ -178,7 +188,7 @@ func (s *Statx) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
// CopyIn implements marshal.Marshallable.CopyIn.
//go:nosplit
func (s *Statx) CopyIn(task marshal.Task, addr usermem.Addr) (int, error) {
- if !s.Atime.Packed() && s.Btime.Packed() && s.Ctime.Packed() && s.Mtime.Packed() {
+ if !s.Btime.Packed() && s.Ctime.Packed() && s.Mtime.Packed() && s.Atime.Packed() {
// Type Statx doesn't have a packed layout in memory, fall back to UnmarshalBytes.
buf := task.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
length, err := task.CopyInBytes(addr, buf) // escapes: okay.
@@ -459,6 +469,809 @@ func (n *NumaPolicy) WriteTo(w io.Writer) (int64, error) {
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (i *IPTEntry) SizeBytes() int {
+ return 12 +
+ (*IPTIP)(nil).SizeBytes() +
+ (*XTCounters)(nil).SizeBytes()
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (i *IPTEntry) MarshalBytes(dst []byte) {
+ i.IP.MarshalBytes(dst[:i.IP.SizeBytes()])
+ dst = dst[i.IP.SizeBytes():]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(i.NFCache))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint16(dst[:2], uint16(i.TargetOffset))
+ dst = dst[2:]
+ usermem.ByteOrder.PutUint16(dst[:2], uint16(i.NextOffset))
+ dst = dst[2:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(i.Comeback))
+ dst = dst[4:]
+ i.Counters.MarshalBytes(dst[:i.Counters.SizeBytes()])
+ dst = dst[i.Counters.SizeBytes():]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (i *IPTEntry) UnmarshalBytes(src []byte) {
+ i.IP.UnmarshalBytes(src[:i.IP.SizeBytes()])
+ src = src[i.IP.SizeBytes():]
+ i.NFCache = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ i.TargetOffset = uint16(usermem.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ i.NextOffset = uint16(usermem.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ i.Comeback = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ i.Counters.UnmarshalBytes(src[:i.Counters.SizeBytes()])
+ src = src[i.Counters.SizeBytes():]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (i *IPTEntry) Packed() bool {
+ return i.IP.Packed() && i.Counters.Packed()
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (i *IPTEntry) MarshalUnsafe(dst []byte) {
+ if i.Counters.Packed() && i.IP.Packed() {
+ safecopy.CopyIn(dst, unsafe.Pointer(i))
+ } else {
+ i.MarshalBytes(dst)
+ }
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (i *IPTEntry) UnmarshalUnsafe(src []byte) {
+ if i.IP.Packed() && i.Counters.Packed() {
+ safecopy.CopyOut(unsafe.Pointer(i), src)
+ } else {
+ i.UnmarshalBytes(src)
+ }
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (i *IPTEntry) CopyOutN(task marshal.Task, addr usermem.Addr, limit int) (int, error) {
+ if !i.IP.Packed() && i.Counters.Packed() {
+ // Type IPTEntry doesn't have a packed layout in memory, fall back to MarshalBytes.
+ buf := task.CopyScratchBuffer(i.SizeBytes()) // escapes: okay.
+ i.MarshalBytes(buf) // escapes: fallback.
+ return task.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (i *IPTEntry) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return i.CopyOutN(task, addr, i.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (i *IPTEntry) CopyIn(task marshal.Task, addr usermem.Addr) (int, error) {
+ if !i.IP.Packed() && i.Counters.Packed() {
+ // Type IPTEntry doesn't have a packed layout in memory, fall back to UnmarshalBytes.
+ buf := task.CopyScratchBuffer(i.SizeBytes()) // escapes: okay.
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Unmarshal unconditionally. If we had a short copy-in, this results in a
+ // partially unmarshalled struct.
+ i.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (i *IPTEntry) WriteTo(w io.Writer) (int64, error) {
+ if !i.Counters.Packed() && i.IP.Packed() {
+ // Type IPTEntry doesn't have a packed layout in memory, fall back to MarshalBytes.
+ buf := make([]byte, i.SizeBytes())
+ i.MarshalBytes(buf)
+ length, err := w.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (i *IPTIP) SizeBytes() int {
+ return 4 +
+ (*InetAddr)(nil).SizeBytes() +
+ (*InetAddr)(nil).SizeBytes() +
+ (*InetAddr)(nil).SizeBytes() +
+ (*InetAddr)(nil).SizeBytes() +
+ 1*IFNAMSIZ +
+ 1*IFNAMSIZ +
+ 1*IFNAMSIZ +
+ 1*IFNAMSIZ
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (i *IPTIP) MarshalBytes(dst []byte) {
+ i.Src.MarshalBytes(dst[:i.Src.SizeBytes()])
+ dst = dst[i.Src.SizeBytes():]
+ i.Dst.MarshalBytes(dst[:i.Dst.SizeBytes()])
+ dst = dst[i.Dst.SizeBytes():]
+ i.SrcMask.MarshalBytes(dst[:i.SrcMask.SizeBytes()])
+ dst = dst[i.SrcMask.SizeBytes():]
+ i.DstMask.MarshalBytes(dst[:i.DstMask.SizeBytes()])
+ dst = dst[i.DstMask.SizeBytes():]
+ for idx := 0; idx < IFNAMSIZ; idx++ {
+ dst[0] = byte(i.InputInterface[idx])
+ dst = dst[1:]
+ }
+ for idx := 0; idx < IFNAMSIZ; idx++ {
+ dst[0] = byte(i.OutputInterface[idx])
+ dst = dst[1:]
+ }
+ for idx := 0; idx < IFNAMSIZ; idx++ {
+ dst[0] = byte(i.InputInterfaceMask[idx])
+ dst = dst[1:]
+ }
+ for idx := 0; idx < IFNAMSIZ; idx++ {
+ dst[0] = byte(i.OutputInterfaceMask[idx])
+ dst = dst[1:]
+ }
+ usermem.ByteOrder.PutUint16(dst[:2], uint16(i.Protocol))
+ dst = dst[2:]
+ dst[0] = byte(i.Flags)
+ dst = dst[1:]
+ dst[0] = byte(i.InverseFlags)
+ dst = dst[1:]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (i *IPTIP) UnmarshalBytes(src []byte) {
+ i.Src.UnmarshalBytes(src[:i.Src.SizeBytes()])
+ src = src[i.Src.SizeBytes():]
+ i.Dst.UnmarshalBytes(src[:i.Dst.SizeBytes()])
+ src = src[i.Dst.SizeBytes():]
+ i.SrcMask.UnmarshalBytes(src[:i.SrcMask.SizeBytes()])
+ src = src[i.SrcMask.SizeBytes():]
+ i.DstMask.UnmarshalBytes(src[:i.DstMask.SizeBytes()])
+ src = src[i.DstMask.SizeBytes():]
+ for idx := 0; idx < IFNAMSIZ; idx++ {
+ i.InputInterface[idx] = src[0]
+ src = src[1:]
+ }
+ for idx := 0; idx < IFNAMSIZ; idx++ {
+ i.OutputInterface[idx] = src[0]
+ src = src[1:]
+ }
+ for idx := 0; idx < IFNAMSIZ; idx++ {
+ i.InputInterfaceMask[idx] = src[0]
+ src = src[1:]
+ }
+ for idx := 0; idx < IFNAMSIZ; idx++ {
+ i.OutputInterfaceMask[idx] = src[0]
+ src = src[1:]
+ }
+ i.Protocol = uint16(usermem.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ i.Flags = uint8(src[0])
+ src = src[1:]
+ i.InverseFlags = uint8(src[0])
+ src = src[1:]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (i *IPTIP) Packed() bool {
+ return i.Src.Packed() && i.Dst.Packed() && i.SrcMask.Packed() && i.DstMask.Packed()
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (i *IPTIP) MarshalUnsafe(dst []byte) {
+ if i.Src.Packed() && i.Dst.Packed() && i.SrcMask.Packed() && i.DstMask.Packed() {
+ safecopy.CopyIn(dst, unsafe.Pointer(i))
+ } else {
+ i.MarshalBytes(dst)
+ }
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (i *IPTIP) UnmarshalUnsafe(src []byte) {
+ if i.Src.Packed() && i.Dst.Packed() && i.SrcMask.Packed() && i.DstMask.Packed() {
+ safecopy.CopyOut(unsafe.Pointer(i), src)
+ } else {
+ i.UnmarshalBytes(src)
+ }
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (i *IPTIP) CopyOutN(task marshal.Task, addr usermem.Addr, limit int) (int, error) {
+ if !i.SrcMask.Packed() && i.DstMask.Packed() && i.Src.Packed() && i.Dst.Packed() {
+ // Type IPTIP doesn't have a packed layout in memory, fall back to MarshalBytes.
+ buf := task.CopyScratchBuffer(i.SizeBytes()) // escapes: okay.
+ i.MarshalBytes(buf) // escapes: fallback.
+ return task.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (i *IPTIP) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return i.CopyOutN(task, addr, i.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (i *IPTIP) CopyIn(task marshal.Task, addr usermem.Addr) (int, error) {
+ if !i.Src.Packed() && i.Dst.Packed() && i.SrcMask.Packed() && i.DstMask.Packed() {
+ // Type IPTIP doesn't have a packed layout in memory, fall back to UnmarshalBytes.
+ buf := task.CopyScratchBuffer(i.SizeBytes()) // escapes: okay.
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Unmarshal unconditionally. If we had a short copy-in, this results in a
+ // partially unmarshalled struct.
+ i.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (i *IPTIP) WriteTo(w io.Writer) (int64, error) {
+ if !i.Src.Packed() && i.Dst.Packed() && i.SrcMask.Packed() && i.DstMask.Packed() {
+ // Type IPTIP doesn't have a packed layout in memory, fall back to MarshalBytes.
+ buf := make([]byte, i.SizeBytes())
+ i.MarshalBytes(buf)
+ length, err := w.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (x *XTCounters) SizeBytes() int {
+ return 16
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (x *XTCounters) MarshalBytes(dst []byte) {
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(x.Pcnt))
+ dst = dst[8:]
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(x.Bcnt))
+ dst = dst[8:]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (x *XTCounters) UnmarshalBytes(src []byte) {
+ x.Pcnt = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ x.Bcnt = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (x *XTCounters) Packed() bool {
+ return true
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (x *XTCounters) MarshalUnsafe(dst []byte) {
+ safecopy.CopyIn(dst, unsafe.Pointer(x))
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (x *XTCounters) UnmarshalUnsafe(src []byte) {
+ safecopy.CopyOut(unsafe.Pointer(x), src)
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (x *XTCounters) CopyOutN(task marshal.Task, addr usermem.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(x)))
+ hdr.Len = x.SizeBytes()
+ hdr.Cap = x.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that x
+ // must live until the use above.
+ runtime.KeepAlive(x)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (x *XTCounters) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return x.CopyOutN(task, addr, x.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (x *XTCounters) CopyIn(task marshal.Task, addr usermem.Addr) (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(x)))
+ hdr.Len = x.SizeBytes()
+ hdr.Cap = x.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that x
+ // must live until the use above.
+ runtime.KeepAlive(x)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (x *XTCounters) WriteTo(w 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(x)))
+ hdr.Len = x.SizeBytes()
+ hdr.Cap = x.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that x
+ // must live until the use above.
+ runtime.KeepAlive(x)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (i *IPTGetinfo) SizeBytes() int {
+ return 12 +
+ (*TableName)(nil).SizeBytes() +
+ 4*NF_INET_NUMHOOKS +
+ 4*NF_INET_NUMHOOKS
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (i *IPTGetinfo) MarshalBytes(dst []byte) {
+ i.Name.MarshalBytes(dst[:i.Name.SizeBytes()])
+ dst = dst[i.Name.SizeBytes():]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(i.ValidHooks))
+ dst = dst[4:]
+ for idx := 0; idx < NF_INET_NUMHOOKS; idx++ {
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(i.HookEntry[idx]))
+ dst = dst[4:]
+ }
+ for idx := 0; idx < NF_INET_NUMHOOKS; idx++ {
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(i.Underflow[idx]))
+ dst = dst[4:]
+ }
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(i.NumEntries))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(i.Size))
+ dst = dst[4:]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (i *IPTGetinfo) UnmarshalBytes(src []byte) {
+ i.Name.UnmarshalBytes(src[:i.Name.SizeBytes()])
+ src = src[i.Name.SizeBytes():]
+ i.ValidHooks = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ for idx := 0; idx < NF_INET_NUMHOOKS; idx++ {
+ i.HookEntry[idx] = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ }
+ for idx := 0; idx < NF_INET_NUMHOOKS; idx++ {
+ i.Underflow[idx] = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ }
+ i.NumEntries = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ i.Size = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (i *IPTGetinfo) Packed() bool {
+ return i.Name.Packed()
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (i *IPTGetinfo) MarshalUnsafe(dst []byte) {
+ if i.Name.Packed() {
+ safecopy.CopyIn(dst, unsafe.Pointer(i))
+ } else {
+ i.MarshalBytes(dst)
+ }
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (i *IPTGetinfo) UnmarshalUnsafe(src []byte) {
+ if i.Name.Packed() {
+ safecopy.CopyOut(unsafe.Pointer(i), src)
+ } else {
+ i.UnmarshalBytes(src)
+ }
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (i *IPTGetinfo) CopyOutN(task marshal.Task, addr usermem.Addr, limit int) (int, error) {
+ if !i.Name.Packed() {
+ // Type IPTGetinfo doesn't have a packed layout in memory, fall back to MarshalBytes.
+ buf := task.CopyScratchBuffer(i.SizeBytes()) // escapes: okay.
+ i.MarshalBytes(buf) // escapes: fallback.
+ return task.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (i *IPTGetinfo) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return i.CopyOutN(task, addr, i.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (i *IPTGetinfo) CopyIn(task marshal.Task, addr usermem.Addr) (int, error) {
+ if !i.Name.Packed() {
+ // Type IPTGetinfo doesn't have a packed layout in memory, fall back to UnmarshalBytes.
+ buf := task.CopyScratchBuffer(i.SizeBytes()) // escapes: okay.
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Unmarshal unconditionally. If we had a short copy-in, this results in a
+ // partially unmarshalled struct.
+ i.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (i *IPTGetinfo) WriteTo(w io.Writer) (int64, error) {
+ if !i.Name.Packed() {
+ // Type IPTGetinfo doesn't have a packed layout in memory, fall back to MarshalBytes.
+ buf := make([]byte, i.SizeBytes())
+ i.MarshalBytes(buf)
+ length, err := w.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (i *IPTGetEntries) SizeBytes() int {
+ return 4 +
+ (*TableName)(nil).SizeBytes() +
+ 1*4
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (i *IPTGetEntries) MarshalBytes(dst []byte) {
+ i.Name.MarshalBytes(dst[:i.Name.SizeBytes()])
+ dst = dst[i.Name.SizeBytes():]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(i.Size))
+ dst = dst[4:]
+ // Padding: dst[:sizeof(byte)*4] ~= [4]byte{0}
+ dst = dst[1*(4):]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (i *IPTGetEntries) UnmarshalBytes(src []byte) {
+ i.Name.UnmarshalBytes(src[:i.Name.SizeBytes()])
+ src = src[i.Name.SizeBytes():]
+ i.Size = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ // Padding: ~ copy([4]byte(i._), src[:sizeof(byte)*4])
+ src = src[1*(4):]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (i *IPTGetEntries) Packed() bool {
+ return i.Name.Packed()
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (i *IPTGetEntries) MarshalUnsafe(dst []byte) {
+ if i.Name.Packed() {
+ safecopy.CopyIn(dst, unsafe.Pointer(i))
+ } else {
+ i.MarshalBytes(dst)
+ }
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (i *IPTGetEntries) UnmarshalUnsafe(src []byte) {
+ if i.Name.Packed() {
+ safecopy.CopyOut(unsafe.Pointer(i), src)
+ } else {
+ i.UnmarshalBytes(src)
+ }
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (i *IPTGetEntries) CopyOutN(task marshal.Task, addr usermem.Addr, limit int) (int, error) {
+ if !i.Name.Packed() {
+ // Type IPTGetEntries doesn't have a packed layout in memory, fall back to MarshalBytes.
+ buf := task.CopyScratchBuffer(i.SizeBytes()) // escapes: okay.
+ i.MarshalBytes(buf) // escapes: fallback.
+ return task.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (i *IPTGetEntries) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return i.CopyOutN(task, addr, i.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (i *IPTGetEntries) CopyIn(task marshal.Task, addr usermem.Addr) (int, error) {
+ if !i.Name.Packed() {
+ // Type IPTGetEntries doesn't have a packed layout in memory, fall back to UnmarshalBytes.
+ buf := task.CopyScratchBuffer(i.SizeBytes()) // escapes: okay.
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Unmarshal unconditionally. If we had a short copy-in, this results in a
+ // partially unmarshalled struct.
+ i.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (i *IPTGetEntries) WriteTo(w io.Writer) (int64, error) {
+ if !i.Name.Packed() {
+ // Type IPTGetEntries doesn't have a packed layout in memory, fall back to MarshalBytes.
+ buf := make([]byte, i.SizeBytes())
+ i.MarshalBytes(buf)
+ length, err := w.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+//go:nosplit
+func (t *TableName) SizeBytes() int {
+ return 1 * XT_TABLE_MAXNAMELEN
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (t *TableName) MarshalBytes(dst []byte) {
+ for idx := 0; idx < XT_TABLE_MAXNAMELEN; idx++ {
+ dst[0] = byte(t[idx])
+ dst = dst[1:]
+ }
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (t *TableName) UnmarshalBytes(src []byte) {
+ for idx := 0; idx < XT_TABLE_MAXNAMELEN; idx++ {
+ t[idx] = src[0]
+ src = src[1:]
+ }
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (t *TableName) Packed() bool {
+ // Array newtypes are always packed.
+ return true
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (t *TableName) MarshalUnsafe(dst []byte) {
+ safecopy.CopyIn(dst, unsafe.Pointer(t))
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (t *TableName) UnmarshalUnsafe(src []byte) {
+ safecopy.CopyOut(unsafe.Pointer(t), src)
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (t *TableName) CopyOutN(task marshal.Task, addr usermem.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(t)))
+ hdr.Len = t.SizeBytes()
+ hdr.Cap = t.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that t
+ // must live until the use above.
+ runtime.KeepAlive(t)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (t *TableName) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return t.CopyOutN(task, addr, t.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (t *TableName) CopyIn(task marshal.Task, addr usermem.Addr) (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(t)))
+ hdr.Len = t.SizeBytes()
+ hdr.Cap = t.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that t
+ // must live until the use above.
+ runtime.KeepAlive(t)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (t *TableName) WriteTo(w 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(t)))
+ hdr.Len = t.SizeBytes()
+ hdr.Cap = t.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that t
+ // must live until the use above.
+ runtime.KeepAlive(t)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
func (r *RSeqCriticalSection) SizeBytes() int {
return 32
}
@@ -653,6 +1466,560 @@ func (s *SignalSet) WriteTo(w io.Writer) (int64, error) {
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
+//go:nosplit
+func (i *InetAddr) SizeBytes() int {
+ return 1 * 4
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (i *InetAddr) MarshalBytes(dst []byte) {
+ for idx := 0; idx < 4; idx++ {
+ dst[0] = byte(i[idx])
+ dst = dst[1:]
+ }
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (i *InetAddr) UnmarshalBytes(src []byte) {
+ for idx := 0; idx < 4; idx++ {
+ i[idx] = src[0]
+ src = src[1:]
+ }
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (i *InetAddr) Packed() bool {
+ // Array newtypes are always packed.
+ return true
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (i *InetAddr) MarshalUnsafe(dst []byte) {
+ safecopy.CopyIn(dst, unsafe.Pointer(i))
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (i *InetAddr) UnmarshalUnsafe(src []byte) {
+ safecopy.CopyOut(unsafe.Pointer(i), src)
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (i *InetAddr) CopyOutN(task marshal.Task, addr usermem.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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (i *InetAddr) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return i.CopyOutN(task, addr, i.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (i *InetAddr) CopyIn(task marshal.Task, addr usermem.Addr) (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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (i *InetAddr) WriteTo(w 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(i)))
+ hdr.Len = i.SizeBytes()
+ hdr.Cap = i.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that i
+ // must live until the use above.
+ runtime.KeepAlive(i)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (l *Linger) SizeBytes() int {
+ return 8
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (l *Linger) MarshalBytes(dst []byte) {
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(l.OnOff))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(l.Linger))
+ dst = dst[4:]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (l *Linger) UnmarshalBytes(src []byte) {
+ l.OnOff = int32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ l.Linger = int32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (l *Linger) Packed() bool {
+ return true
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (l *Linger) MarshalUnsafe(dst []byte) {
+ safecopy.CopyIn(dst, unsafe.Pointer(l))
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (l *Linger) UnmarshalUnsafe(src []byte) {
+ safecopy.CopyOut(unsafe.Pointer(l), src)
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (l *Linger) CopyOutN(task marshal.Task, addr usermem.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(l)))
+ hdr.Len = l.SizeBytes()
+ hdr.Cap = l.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that l
+ // must live until the use above.
+ runtime.KeepAlive(l)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (l *Linger) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return l.CopyOutN(task, addr, l.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (l *Linger) CopyIn(task marshal.Task, addr usermem.Addr) (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(l)))
+ hdr.Len = l.SizeBytes()
+ hdr.Cap = l.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that l
+ // must live until the use above.
+ runtime.KeepAlive(l)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (l *Linger) WriteTo(w 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(l)))
+ hdr.Len = l.SizeBytes()
+ hdr.Cap = l.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that l
+ // must live until the use above.
+ runtime.KeepAlive(l)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (t *TCPInfo) SizeBytes() int {
+ return 192
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (t *TCPInfo) MarshalBytes(dst []byte) {
+ dst[0] = byte(t.State)
+ dst = dst[1:]
+ dst[0] = byte(t.CaState)
+ dst = dst[1:]
+ dst[0] = byte(t.Retransmits)
+ dst = dst[1:]
+ dst[0] = byte(t.Probes)
+ dst = dst[1:]
+ dst[0] = byte(t.Backoff)
+ dst = dst[1:]
+ dst[0] = byte(t.Options)
+ dst = dst[1:]
+ dst[0] = byte(t.WindowScale)
+ dst = dst[1:]
+ dst[0] = byte(t.DeliveryRateAppLimited)
+ dst = dst[1:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.RTO))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.ATO))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.SndMss))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.RcvMss))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.Unacked))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.Sacked))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.Lost))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.Retrans))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.Fackets))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.LastDataSent))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.LastAckSent))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.LastDataRecv))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.LastAckRecv))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.PMTU))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.RcvSsthresh))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.RTT))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.RTTVar))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.SndSsthresh))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.SndCwnd))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.Advmss))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.Reordering))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.RcvRTT))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.RcvSpace))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.TotalRetrans))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(t.PacingRate))
+ dst = dst[8:]
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(t.MaxPacingRate))
+ dst = dst[8:]
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(t.BytesAcked))
+ dst = dst[8:]
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(t.BytesReceived))
+ dst = dst[8:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.SegsOut))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.SegsIn))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.NotSentBytes))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.MinRTT))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.DataSegsIn))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(t.DataSegsOut))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(t.DeliveryRate))
+ dst = dst[8:]
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(t.BusyTime))
+ dst = dst[8:]
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(t.RwndLimited))
+ dst = dst[8:]
+ usermem.ByteOrder.PutUint64(dst[:8], uint64(t.SndBufLimited))
+ dst = dst[8:]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (t *TCPInfo) UnmarshalBytes(src []byte) {
+ t.State = uint8(src[0])
+ src = src[1:]
+ t.CaState = uint8(src[0])
+ src = src[1:]
+ t.Retransmits = uint8(src[0])
+ src = src[1:]
+ t.Probes = uint8(src[0])
+ src = src[1:]
+ t.Backoff = uint8(src[0])
+ src = src[1:]
+ t.Options = uint8(src[0])
+ src = src[1:]
+ t.WindowScale = uint8(src[0])
+ src = src[1:]
+ t.DeliveryRateAppLimited = uint8(src[0])
+ src = src[1:]
+ t.RTO = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.ATO = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.SndMss = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.RcvMss = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.Unacked = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.Sacked = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.Lost = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.Retrans = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.Fackets = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.LastDataSent = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.LastAckSent = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.LastDataRecv = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.LastAckRecv = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.PMTU = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.RcvSsthresh = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.RTT = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.RTTVar = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.SndSsthresh = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.SndCwnd = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.Advmss = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.Reordering = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.RcvRTT = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.RcvSpace = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.TotalRetrans = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.PacingRate = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ t.MaxPacingRate = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ t.BytesAcked = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ t.BytesReceived = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ t.SegsOut = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.SegsIn = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.NotSentBytes = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.MinRTT = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.DataSegsIn = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.DataSegsOut = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ t.DeliveryRate = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ t.BusyTime = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ t.RwndLimited = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ t.SndBufLimited = uint64(usermem.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (t *TCPInfo) Packed() bool {
+ return true
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (t *TCPInfo) MarshalUnsafe(dst []byte) {
+ safecopy.CopyIn(dst, unsafe.Pointer(t))
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (t *TCPInfo) UnmarshalUnsafe(src []byte) {
+ safecopy.CopyOut(unsafe.Pointer(t), src)
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (t *TCPInfo) CopyOutN(task marshal.Task, addr usermem.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(t)))
+ hdr.Len = t.SizeBytes()
+ hdr.Cap = t.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that t
+ // must live until the use above.
+ runtime.KeepAlive(t)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (t *TCPInfo) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return t.CopyOutN(task, addr, t.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (t *TCPInfo) CopyIn(task marshal.Task, addr usermem.Addr) (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(t)))
+ hdr.Len = t.SizeBytes()
+ hdr.Cap = t.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that t
+ // must live until the use above.
+ runtime.KeepAlive(t)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (t *TCPInfo) WriteTo(w 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(t)))
+ hdr.Len = t.SizeBytes()
+ hdr.Cap = t.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that t
+ // must live until the use above.
+ runtime.KeepAlive(t)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (c *ControlMessageCredentials) SizeBytes() int {
+ return 12
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (c *ControlMessageCredentials) MarshalBytes(dst []byte) {
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(c.PID))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(c.UID))
+ dst = dst[4:]
+ usermem.ByteOrder.PutUint32(dst[:4], uint32(c.GID))
+ dst = dst[4:]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (c *ControlMessageCredentials) UnmarshalBytes(src []byte) {
+ c.PID = int32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ c.UID = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ c.GID = uint32(usermem.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (c *ControlMessageCredentials) Packed() bool {
+ return true
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (c *ControlMessageCredentials) MarshalUnsafe(dst []byte) {
+ safecopy.CopyIn(dst, unsafe.Pointer(c))
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (c *ControlMessageCredentials) UnmarshalUnsafe(src []byte) {
+ safecopy.CopyOut(unsafe.Pointer(c), src)
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (c *ControlMessageCredentials) CopyOutN(task marshal.Task, addr usermem.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(c)))
+ hdr.Len = c.SizeBytes()
+ hdr.Cap = c.SizeBytes()
+
+ length, err := task.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that c
+ // must live until the use above.
+ runtime.KeepAlive(c)
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (c *ControlMessageCredentials) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ return c.CopyOutN(task, addr, c.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (c *ControlMessageCredentials) CopyIn(task marshal.Task, addr usermem.Addr) (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(c)))
+ hdr.Len = c.SizeBytes()
+ hdr.Cap = c.SizeBytes()
+
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that c
+ // must live until the use above.
+ runtime.KeepAlive(c)
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (c *ControlMessageCredentials) WriteTo(w 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(c)))
+ hdr.Len = c.SizeBytes()
+ hdr.Cap = c.SizeBytes()
+
+ length, err := w.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that c
+ // must live until the use above.
+ runtime.KeepAlive(c)
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
func (t *Timespec) SizeBytes() int {
return 16
}
diff --git a/pkg/abi/linux/netfilter.go b/pkg/abi/linux/netfilter.go
index 46d8b0b42..a91f9f018 100644
--- a/pkg/abi/linux/netfilter.go
+++ b/pkg/abi/linux/netfilter.go
@@ -14,6 +14,14 @@
package linux
+import (
+ "io"
+
+ "gvisor.dev/gvisor/pkg/usermem"
+ "gvisor.dev/gvisor/tools/go_marshal/marshal"
+ "gvisor.dev/gvisor/tools/go_marshal/primitive"
+)
+
// This file contains structures required to support netfilter, specifically
// the iptables tool.
@@ -76,6 +84,8 @@ const (
// 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
@@ -112,21 +122,41 @@ type IPTEntry struct {
// SizeOfIPTEntry is the size of an IPTEntry.
const SizeOfIPTEntry = 112
-// KernelIPTEntry is identical to IPTEntry, but includes the Elems field. This
-// struct marshaled via the binary package to write an IPTEntry to userspace.
+// KernelIPTEntry is identical to IPTEntry, but includes the Elems field.
+// KernelIPTEntry itself is not Marshallable but it implements some methods of
+// marshal.Marshallable that help in other implementations of Marshallable.
type KernelIPTEntry struct {
- IPTEntry
+ 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 []byte
+ 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) {
+ ke.Entry.MarshalBytes(dst)
+ ke.Elems.MarshalBytes(dst[ke.Entry.SizeBytes():])
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (ke *KernelIPTEntry) UnmarshalBytes(src []byte) {
+ ke.Entry.UnmarshalBytes(src)
+ ke.Elems.UnmarshalBytes(src[ke.Entry.SizeBytes():])
}
// 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
@@ -189,6 +219,8 @@ 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
@@ -321,6 +353,8 @@ const SizeOfXTRedirectTarget = 56
// 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
@@ -336,6 +370,8 @@ 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
@@ -350,13 +386,103 @@ type IPTGetEntries struct {
const SizeOfIPTGetEntries = 40
// KernelIPTGetEntries is identical to IPTGetEntries, but includes the
-// Entrytable field. This struct marshaled via the binary package to write an
-// KernelIPTGetEntries to userspace.
+// Entrytable field. This has been manually made marshal.Marshallable since it
+// is dynamically sized.
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) {
+ ke.IPTGetEntries.MarshalBytes(dst)
+ marshalledUntil := ke.IPTGetEntries.SizeBytes()
+ for i := 0; i < len(ke.Entrytable); i++ {
+ ke.Entrytable[i].MarshalBytes(dst[marshalledUntil:])
+ marshalledUntil += ke.Entrytable[i].SizeBytes()
+ }
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (ke *KernelIPTGetEntries) UnmarshalBytes(src []byte) {
+ ke.IPTGetEntries.UnmarshalBytes(src)
+ unmarshalledUntil := ke.IPTGetEntries.SizeBytes()
+ for i := 0; i < len(ke.Entrytable); i++ {
+ ke.Entrytable[i].UnmarshalBytes(src[unmarshalledUntil:])
+ unmarshalledUntil += ke.Entrytable[i].SizeBytes()
+ }
+}
+
+// Packed implements marshal.Marshallable.Packed.
+func (ke *KernelIPTGetEntries) Packed() bool {
+ // KernelIPTGetEntries isn't packed because the ke.Entrytable contains an
+ // indirection to the actual data we want to marshal (the slice data
+ // pointer), and the memory for KernelIPTGetEntries contains the slice
+ // header which we don't want to marshal.
+ return false
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (ke *KernelIPTGetEntries) MarshalUnsafe(dst []byte) {
+ // Fall back to safe Marshal because the type in not packed.
+ ke.MarshalBytes(dst)
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (ke *KernelIPTGetEntries) UnmarshalUnsafe(src []byte) {
+ // Fall back to safe Unmarshal because the type in not packed.
+ ke.UnmarshalBytes(src)
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+func (ke *KernelIPTGetEntries) CopyIn(task marshal.Task, addr usermem.Addr) (int, error) {
+ buf := task.CopyScratchBuffer(ke.SizeBytes()) // escapes: okay.
+ length, err := task.CopyInBytes(addr, buf) // escapes: okay.
+ // Unmarshal unconditionally. If we had a short copy-in, this results in a
+ // partially unmarshalled struct.
+ ke.UnmarshalBytes(buf) // escapes: fallback.
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+func (ke *KernelIPTGetEntries) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) {
+ // Type KernelIPTGetEntries doesn't have a packed layout in memory, fall
+ // back to MarshalBytes.
+ return task.CopyOutBytes(addr, ke.marshalAll(task))
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+func (ke *KernelIPTGetEntries) CopyOutN(task marshal.Task, addr usermem.Addr, limit int) (int, error) {
+ // Type KernelIPTGetEntries doesn't have a packed layout in memory, fall
+ // back to MarshalBytes.
+ return task.CopyOutBytes(addr, ke.marshalAll(task)[:limit])
+}
+
+func (ke *KernelIPTGetEntries) marshalAll(task marshal.Task) []byte {
+ buf := task.CopyScratchBuffer(ke.SizeBytes())
+ ke.MarshalBytes(buf)
+ return buf
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (ke *KernelIPTGetEntries) WriteTo(w io.Writer) (int64, error) {
+ buf := make([]byte, ke.SizeBytes())
+ ke.MarshalBytes(buf)
+ length, err := w.Write(buf)
+ return int64(length), err
+}
+
+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.
@@ -374,12 +500,6 @@ type IPTReplace struct {
// Entries [0]IPTEntry
}
-// KernelIPTReplace is identical to IPTReplace, but includes the Entries field.
-type KernelIPTReplace struct {
- IPTReplace
- Entries [0]IPTEntry
-}
-
// SizeOfIPTReplace is the size of an IPTReplace.
const SizeOfIPTReplace = 96
@@ -392,6 +512,8 @@ func (en ExtensionName) String() string {
}
// TableName holds the name of a netfilter table.
+//
+// +marshal
type TableName [XT_TABLE_MAXNAMELEN]byte
// String implements fmt.Stringer.
diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go
index 95337c168..c24a8216e 100644
--- a/pkg/abi/linux/socket.go
+++ b/pkg/abi/linux/socket.go
@@ -234,6 +234,8 @@ const (
const SockAddrMax = 128
// InetAddr is struct in_addr, from uapi/linux/in.h.
+//
+// +marshal
type InetAddr [4]byte
// SockAddrInet is struct sockaddr_in, from uapi/linux/in.h.
@@ -303,6 +305,8 @@ 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
@@ -317,6 +321,8 @@ const SizeOfLinger = 8
// the end of this struct or within existing unusued 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 uint8
CaState uint8
@@ -414,6 +420,8 @@ var SizeOfControlMessageHeader = int(binary.Size(ControlMessageHeader{}))
// 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