diff options
Diffstat (limited to 'pkg/abi')
-rw-r--r-- | pkg/abi/linux/linux_abi_autogen_unsafe.go | 1373 | ||||
-rw-r--r-- | pkg/abi/linux/netfilter.go | 146 | ||||
-rw-r--r-- | pkg/abi/linux/socket.go | 8 |
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 |