setSockOptPacket implements the linux setsockopt(2) when the level is SOL_PACKET.
(t *kernel.Task, ep commonEndpoint, name int, optVal []byte)
| 2970 | |
| 2971 | // setSockOptPacket implements the linux setsockopt(2) when the level is SOL_PACKET. |
| 2972 | func (s *sock) setSockOptPacket(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *syserr.Error { |
| 2973 | switch name { |
| 2974 | case linux.PACKET_RX_RING: |
| 2975 | var tpacketReq linux.TpacketReq |
| 2976 | if len(optVal) < tpacketReq.SizeBytes() { |
| 2977 | return syserr.ErrInvalidArgument |
| 2978 | } |
| 2979 | tpacketReq.UnmarshalBytes(optVal) |
| 2980 | req := tcpip.TpacketReq{ |
| 2981 | TpBlockSize: tpacketReq.TpBlockSize, |
| 2982 | TpBlockNr: tpacketReq.TpBlockNr, |
| 2983 | TpFrameSize: tpacketReq.TpFrameSize, |
| 2984 | TpFrameNr: tpacketReq.TpFrameNr, |
| 2985 | } |
| 2986 | if err := ep.SetSockOpt(&req); err != nil { |
| 2987 | return syserr.TranslateNetstackError(err) |
| 2988 | } |
| 2989 | if ep, ok := ep.(stack.MappablePacketEndpoint); ok { |
| 2990 | var pme *packetmmap.Endpoint |
| 2991 | if ep.GetPacketMMapEndpoint() != nil { |
| 2992 | pme = ep.GetPacketMMapEndpoint().(*packetmmap.Endpoint) |
| 2993 | if pme.Mapped() { |
| 2994 | return syserr.ErrBusy |
| 2995 | } |
| 2996 | } else { |
| 2997 | pme = &packetmmap.Endpoint{} |
| 2998 | } |
| 2999 | opts := ep.GetPacketMMapOpts(&req, true /* isRx */) |
| 3000 | if opts.Req.TpFrameNr != 0 || opts.Req.TpBlockNr != 0 { |
| 3001 | if err := pme.Init(t, opts); err != nil { |
| 3002 | return syserr.FromError(err) |
| 3003 | } |
| 3004 | ep.SetPacketMMapEndpoint(pme) |
| 3005 | } |
| 3006 | } else { |
| 3007 | return syserr.ErrNotSupported |
| 3008 | } |
| 3009 | return nil |
| 3010 | case linux.PACKET_VERSION: |
| 3011 | if len(optVal) < sizeOfInt32 { |
| 3012 | return syserr.ErrInvalidArgument |
| 3013 | } |
| 3014 | v := hostarch.ByteOrder.Uint32(optVal) |
| 3015 | return syserr.TranslateNetstackError(ep.SetSockOptInt(tcpip.PacketMMapVersionOption, int(v))) |
| 3016 | case linux.PACKET_RESERVE: |
| 3017 | if len(optVal) < sizeOfInt32 { |
| 3018 | return syserr.ErrInvalidArgument |
| 3019 | } |
| 3020 | v := hostarch.ByteOrder.Uint32(optVal) |
| 3021 | return syserr.TranslateNetstackError(ep.SetSockOptInt(tcpip.PacketMMapReserveOption, int(v))) |
| 3022 | case linux.PACKET_ADD_MEMBERSHIP, linux.PACKET_AUXDATA: |
| 3023 | // Silently ignore these options. |
| 3024 | incrementBadSetSocketOptionMetric(t, &socketLevelPacketFieldValue, name) |
| 3025 | return nil |
| 3026 | default: |
| 3027 | incrementBadSetSocketOptionMetric(t, &socketLevelIPFieldValue, name) |
| 3028 | return syserr.ErrNotSupported |
| 3029 | } |
no test coverage detected