Skip to content

Commit

Permalink
Add constants and types related to the implementation of PACKET_MMAP.
Browse files Browse the repository at this point in the history
This is the first in a series of changes that implements PACKET_MMAP.

PiperOrigin-RevId: 716014872
  • Loading branch information
manninglucas authored and gvisor-bot committed Jan 16, 2025
1 parent 689db80 commit 25b1d71
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 0 deletions.
66 changes: 66 additions & 0 deletions pkg/abi/linux/socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,72 @@ const (
PACKET_OUTGOING = 4 // Outgoing of any type
)

// Packet socket options from <linux/if_packet.h>
const (
PACKET_RX_RING = 5
)

// Statuses for a frame in a packet_mmap ring buffer from <linux/if_packet.h>.
const (
TP_STATUS_KERNEL = 0
TP_STATUS_USER = 0x1
TP_STATUS_COPY = 0x2
TP_STATUS_LOSING = 0x4
TP_STATUS_CSUM_NOT_READY = 0x8
TP_STATUS_VLAN_VALID = 0x10
TP_STATUS_BLK_TMO = 0x20
TP_STATUS_VLAN_TPID_VALID = 0x40
TP_STATUS_CSUM_VALID = 0x80
TP_STATUS_GSO_TCP = 0x100
)

// TpacketReq is the request for a packet_mmap ring buffer from
// <linux/if_packet.h>.
//
// +marshal
type TpacketReq struct {
TpBlockSize uint32
TpBlockNr uint32
TpFrameSize uint32
TpFrameNr uint32
}

// TpacketHdr is the header for a frame in a packet_mmap ring buffer from
// <linux/if_packet.h>.
//
// +marshal
type TpacketHdr struct {
TpStatus uint64
TpLen uint32
TpSnaplen uint32
TpMac uint16
TpNet uint16
TpSec uint32
TpUsec uint32 `marshal:"unaligned"`
}

// TpacketAlignment is the alignment of a frame in a packet_mmap ring buffer
// from <linux/if_packet.h>.
const (
TPACKET_ALIGNMENT = 16
)

// TPACKET_V1 is the version of a packet_mmap ring buffer from
// <linux/if_packet.h> that is implemented in gVisor.
const (
TPACKET_V1 = iota
)

// TPACKET_HDRLEN is the length of a TpacketHdr from <linux/if_packet.h>.
var (
TPACKET_HDRLEN = TPacketAlign(uint32((*TpacketHdr)(nil).SizeBytes()) + uint32((*SockAddrLink)(nil).SizeBytes()))
)

// TPacketAlign aligns a value to the alignment of a TPacket.
func TPacketAlign(x uint32) uint32 {
return (x + TPACKET_ALIGNMENT - 1) &^ (TPACKET_ALIGNMENT - 1)
}

// Socket options from socket.h.
const (
SO_DEBUG = 1
Expand Down
3 changes: 3 additions & 0 deletions pkg/syserr/netstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ var (
ErrMulticastInputCannotBeOutput = New((&tcpip.ErrMulticastInputCannotBeOutput{}).String(), errno.EINVAL)
ErrMissingRequiredFields = New((&tcpip.ErrMissingRequiredFields{}).String(), errno.EINVAL)
ErrNoNet = New((&tcpip.ErrNoNet{}).String(), errno.ENONET)
ErrEndpointBusy = New((&tcpip.ErrEndpointBusy{}).String(), errno.EBUSY)
)

// TranslateNetstackError converts an error from the tcpip package to a sentry
Expand Down Expand Up @@ -149,6 +150,8 @@ func TranslateNetstackError(err tcpip.Error) *Error {
return ErrMulticastInputCannotBeOutput
case *tcpip.ErrMissingRequiredFields:
return ErrMissingRequiredFields
case *tcpip.ErrEndpointBusy:
return ErrEndpointBusy
default:
panic(fmt.Sprintf("unknown error %T", err))
}
Expand Down
18 changes: 18 additions & 0 deletions pkg/tcpip/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,4 +620,22 @@ func (*ErrMulticastInputCannotBeOutput) IgnoreStats() bool {
}
func (*ErrMulticastInputCannotBeOutput) String() string { return "output cannot contain input" }

// ErrEndpointBusy indicates that the operation cannot be completed because the
// endpoint is busy.
//
// +stateify savable
type ErrEndpointBusy struct{}

// isError implements Error.
func (*ErrEndpointBusy) isError() {}

// IgnoreStats implements Error.
func (*ErrEndpointBusy) IgnoreStats() bool {
return true
}

func (*ErrEndpointBusy) String() string {
return "operation cannot be completed because the endpoint is busy"
}

// LINT.ThenChange(../syserr/netstack.go)
13 changes: 13 additions & 0 deletions pkg/tcpip/tcpip.go
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,19 @@ func (*ICMPv6Filter) isGettableSocketOption() {}

func (*ICMPv6Filter) isSettableSocketOption() {}

// TpacketReq is the tpacket_req structure as described in
// https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt
//
// +stateify savable
type TpacketReq struct {
TpBlockSize uint32
TpBlockNr uint32
TpFrameSize uint32
TpFrameNr uint32
}

func (*TpacketReq) isSettableSocketOption() {}

// EndpointState represents the state of an endpoint.
type EndpointState uint8

Expand Down

0 comments on commit 25b1d71

Please sign in to comment.