mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Implement GetSockOpt PACKET_HDRLEN and add a test for tcpdump.
PiperOrigin-RevId: 724445536
This commit is contained in:
committed by
gVisor bot
parent
de6637c27c
commit
9c490f813d
@@ -907,9 +907,9 @@ func GetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int,
|
||||
case linux.SOL_ICMPV6:
|
||||
return getSockOptICMPv6(t, s, ep, name, outLen)
|
||||
|
||||
case linux.SOL_UDP,
|
||||
linux.SOL_RAW,
|
||||
linux.SOL_PACKET:
|
||||
case linux.SOL_PACKET:
|
||||
return getSockOptPacket(t, s, ep, name, outPtr, outLen)
|
||||
case linux.SOL_UDP, linux.SOL_RAW:
|
||||
// Not supported.
|
||||
}
|
||||
|
||||
@@ -1850,6 +1850,29 @@ func getSockOptIP(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int,
|
||||
return nil, syserr.ErrProtocolNotAvailable
|
||||
}
|
||||
|
||||
func getSockOptPacket(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int, outPtr hostarch.Addr, outLen int) (marshal.Marshallable, *syserr.Error) {
|
||||
if _, ok := ep.(tcpip.Endpoint); !ok {
|
||||
log.Warningf("SOL_PACKET options not supported on endpoints other than tcpip.Endpoint: option = %d, endpoint = %T", name, ep)
|
||||
return nil, syserr.ErrUnknownProtocolOption
|
||||
}
|
||||
switch name {
|
||||
case linux.PACKET_HDRLEN:
|
||||
var version primitive.Int32
|
||||
version.CopyIn(t, outPtr)
|
||||
switch version {
|
||||
case linux.TPACKET_V1:
|
||||
v := primitive.Int32(uint32((*linux.TpacketHdr)(nil).SizeBytes()))
|
||||
return &v, nil
|
||||
case linux.TPACKET_V2:
|
||||
v := primitive.Int32(uint32((*linux.Tpacket2Hdr)(nil).SizeBytes()))
|
||||
return &v, nil
|
||||
default:
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
}
|
||||
return nil, syserr.ErrProtocolNotAvailable
|
||||
}
|
||||
|
||||
// SetSockOpt can be used to implement the linux syscall setsockopt(2) for
|
||||
// sockets backed by a commonEndpoint.
|
||||
func SetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, level int, name int, optVal []byte) *syserr.Error {
|
||||
@@ -2761,6 +2784,12 @@ func setSockOptPacket(t *kernel.Task, s socket.Socket, ep commonEndpoint, name i
|
||||
}
|
||||
v := hostarch.ByteOrder.Uint32(optVal)
|
||||
return syserr.TranslateNetstackError(ep.SetSockOptInt(tcpip.PacketMMapVersionOption, int(v)))
|
||||
case linux.PACKET_RESERVE:
|
||||
v := hostarch.ByteOrder.Uint32(optVal)
|
||||
return syserr.TranslateNetstackError(ep.SetSockOptInt(tcpip.PacketMMapReserveOption, int(v)))
|
||||
case linux.PACKET_ADD_MEMBERSHIP, linux.PACKET_AUXDATA:
|
||||
// Silently ignore these options.
|
||||
return nil
|
||||
default:
|
||||
return syserr.ErrNotSupported
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ type Endpoint struct {
|
||||
|
||||
cooked bool
|
||||
packetEP stack.MappablePacketEndpoint
|
||||
reserve uint32
|
||||
nicID tcpip.NICID
|
||||
netProto tcpip.NetworkProtocolNumber
|
||||
version int
|
||||
@@ -99,6 +100,9 @@ func (m *Endpoint) Init(ctx context.Context, opts stack.PacketMMapOpts) error {
|
||||
m.nicID = opts.NICID
|
||||
m.netProto = opts.NetProto
|
||||
m.version = opts.Version
|
||||
m.reserve = opts.Reserve
|
||||
m.nicID = opts.NICID
|
||||
m.netProto = opts.NetProto
|
||||
switch m.version {
|
||||
case linux.TPACKET_V1:
|
||||
m.headerLen = linux.TPACKET_HDRLEN
|
||||
@@ -114,7 +118,7 @@ func (m *Endpoint) Init(ctx context.Context, opts stack.PacketMMapOpts) error {
|
||||
if opts.Req.TpBlockSize%hostarch.PageSize != 0 {
|
||||
return linuxerr.EINVAL
|
||||
}
|
||||
if opts.Req.TpFrameSize < m.headerLen {
|
||||
if opts.Req.TpFrameSize < m.headerLen+m.reserve {
|
||||
return linuxerr.EINVAL
|
||||
}
|
||||
if opts.Req.TpFrameSize&(linux.TPACKET_ALIGNMENT-1) != 0 {
|
||||
@@ -206,14 +210,14 @@ func (m *Endpoint) HandlePacket(nicID tcpip.NICID, netProto tcpip.NetworkProtoco
|
||||
pktBuf.TrimFront(int64(len(pkt.LinkHeader().Slice()) + len(pkt.VirtioNetHeader().Slice())))
|
||||
// Cooked packet endpoints don't include the link-headers in received
|
||||
// packets.
|
||||
netOffset = linux.TPacketAlign(m.headerLen + minMacLen)
|
||||
netOffset = linux.TPacketAlign(m.headerLen+minMacLen) + m.reserve
|
||||
macOffset = netOffset
|
||||
} else {
|
||||
virtioNetHdrLen := uint32(len(pkt.VirtioNetHeader().Slice()))
|
||||
macLen := uint32(len(pkt.LinkHeader().Slice())) + virtioNetHdrLen
|
||||
netOffset = linux.TPacketAlign(m.headerLen + macLen)
|
||||
netOffset = linux.TPacketAlign(m.headerLen+macLen) + m.reserve
|
||||
if macLen < minMacLen {
|
||||
netOffset = linux.TPacketAlign(m.headerLen + minMacLen)
|
||||
netOffset = linux.TPacketAlign(m.headerLen+minMacLen) + m.reserve
|
||||
}
|
||||
if virtioNetHdrLen > 0 {
|
||||
netOffset += virtioNetHdrLen
|
||||
|
||||
Reference in New Issue
Block a user