| // Copyright 2016 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package bpf |
| |
| // A Register is a register of the BPF virtual machine. |
| type Register uint16 |
| |
| const ( |
| // RegA is the accumulator register. RegA is always the |
| // destination register of ALU operations. |
| RegA Register = iota |
| // RegX is the indirection register, used by LoadIndirect |
| // operations. |
| RegX |
| ) |
| |
| // An ALUOp is an arithmetic or logic operation. |
| type ALUOp uint16 |
| |
| // ALU binary operation types. |
| const ( |
| ALUOpAdd ALUOp = iota << 4 |
| ALUOpSub |
| ALUOpMul |
| ALUOpDiv |
| ALUOpOr |
| ALUOpAnd |
| ALUOpShiftLeft |
| ALUOpShiftRight |
| aluOpNeg // Not exported because it's the only unary ALU operation, and gets its own instruction type. |
| ALUOpMod |
| ALUOpXor |
| ) |
| |
| // A JumpTest is a comparison operator used in conditional jumps. |
| type JumpTest uint16 |
| |
| // Supported operators for conditional jumps. |
| // K can be RegX for JumpIfX |
| const ( |
| // K == A |
| JumpEqual JumpTest = iota |
| // K != A |
| JumpNotEqual |
| // K > A |
| JumpGreaterThan |
| // K < A |
| JumpLessThan |
| // K >= A |
| JumpGreaterOrEqual |
| // K <= A |
| JumpLessOrEqual |
| // K & A != 0 |
| JumpBitsSet |
| // K & A == 0 |
| JumpBitsNotSet |
| ) |
| |
| // An Extension is a function call provided by the kernel that |
| // performs advanced operations that are expensive or impossible |
| // within the BPF virtual machine. |
| // |
| // Extensions are only implemented by the Linux kernel. |
| // |
| // TODO: should we prune this list? Some of these extensions seem |
| // either broken or near-impossible to use correctly, whereas other |
| // (len, random, ifindex) are quite useful. |
| type Extension int |
| |
| // Extension functions available in the Linux kernel. |
| const ( |
| // extOffset is the negative maximum number of instructions used |
| // to load instructions by overloading the K argument. |
| extOffset = -0x1000 |
| // ExtLen returns the length of the packet. |
| ExtLen Extension = 1 |
| // ExtProto returns the packet's L3 protocol type. |
| ExtProto Extension = 0 |
| // ExtType returns the packet's type (skb->pkt_type in the kernel) |
| // |
| // TODO: better documentation. How nice an API do we want to |
| // provide for these esoteric extensions? |
| ExtType Extension = 4 |
| // ExtPayloadOffset returns the offset of the packet payload, or |
| // the first protocol header that the kernel does not know how to |
| // parse. |
| ExtPayloadOffset Extension = 52 |
| // ExtInterfaceIndex returns the index of the interface on which |
| // the packet was received. |
| ExtInterfaceIndex Extension = 8 |
| // ExtNetlinkAttr returns the netlink attribute of type X at |
| // offset A. |
| ExtNetlinkAttr Extension = 12 |
| // ExtNetlinkAttrNested returns the nested netlink attribute of |
| // type X at offset A. |
| ExtNetlinkAttrNested Extension = 16 |
| // ExtMark returns the packet's mark value. |
| ExtMark Extension = 20 |
| // ExtQueue returns the packet's assigned hardware queue. |
| ExtQueue Extension = 24 |
| // ExtLinkLayerType returns the packet's hardware address type |
| // (e.g. Ethernet, Infiniband). |
| ExtLinkLayerType Extension = 28 |
| // ExtRXHash returns the packets receive hash. |
| // |
| // TODO: figure out what this rxhash actually is. |
| ExtRXHash Extension = 32 |
| // ExtCPUID returns the ID of the CPU processing the current |
| // packet. |
| ExtCPUID Extension = 36 |
| // ExtVLANTag returns the packet's VLAN tag. |
| ExtVLANTag Extension = 44 |
| // ExtVLANTagPresent returns non-zero if the packet has a VLAN |
| // tag. |
| // |
| // TODO: I think this might be a lie: it reads bit 0x1000 of the |
| // VLAN header, which changed meaning in recent revisions of the |
| // spec - this extension may now return meaningless information. |
| ExtVLANTagPresent Extension = 48 |
| // ExtVLANProto returns 0x8100 if the frame has a VLAN header, |
| // 0x88a8 if the frame has a "Q-in-Q" double VLAN header, or some |
| // other value if no VLAN information is present. |
| ExtVLANProto Extension = 60 |
| // ExtRand returns a uniformly random uint32. |
| ExtRand Extension = 56 |
| ) |
| |
| // The following gives names to various bit patterns used in opcode construction. |
| |
| const ( |
| opMaskCls uint16 = 0x7 |
| // opClsLoad masks |
| opMaskLoadDest = 0x01 |
| opMaskLoadWidth = 0x18 |
| opMaskLoadMode = 0xe0 |
| // opClsALU & opClsJump |
| opMaskOperand = 0x08 |
| opMaskOperator = 0xf0 |
| ) |
| |
| const ( |
| // +---------------+-----------------+---+---+---+ |
| // | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 0 | |
| // +---------------+-----------------+---+---+---+ |
| opClsLoadA uint16 = iota |
| // +---------------+-----------------+---+---+---+ |
| // | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 1 | |
| // +---------------+-----------------+---+---+---+ |
| opClsLoadX |
| // +---+---+---+---+---+---+---+---+ |
| // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | |
| // +---+---+---+---+---+---+---+---+ |
| opClsStoreA |
| // +---+---+---+---+---+---+---+---+ |
| // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | |
| // +---+---+---+---+---+---+---+---+ |
| opClsStoreX |
| // +---------------+-----------------+---+---+---+ |
| // | Operator (4b) | OperandSrc (1b) | 1 | 0 | 0 | |
| // +---------------+-----------------+---+---+---+ |
| opClsALU |
| // +-----------------------------+---+---+---+---+ |
| // | TestOperator (4b) | 0 | 1 | 0 | 1 | |
| // +-----------------------------+---+---+---+---+ |
| opClsJump |
| // +---+-------------------------+---+---+---+---+ |
| // | 0 | 0 | 0 | RetSrc (1b) | 0 | 1 | 1 | 0 | |
| // +---+-------------------------+---+---+---+---+ |
| opClsReturn |
| // +---+-------------------------+---+---+---+---+ |
| // | 0 | 0 | 0 | TXAorTAX (1b) | 0 | 1 | 1 | 1 | |
| // +---+-------------------------+---+---+---+---+ |
| opClsMisc |
| ) |
| |
| const ( |
| opAddrModeImmediate uint16 = iota << 5 |
| opAddrModeAbsolute |
| opAddrModeIndirect |
| opAddrModeScratch |
| opAddrModePacketLen // actually an extension, not an addressing mode. |
| opAddrModeMemShift |
| ) |
| |
| const ( |
| opLoadWidth4 uint16 = iota << 3 |
| opLoadWidth2 |
| opLoadWidth1 |
| ) |
| |
| // Operand for ALU and Jump instructions |
| type opOperand uint16 |
| |
| // Supported operand sources. |
| const ( |
| opOperandConstant opOperand = iota << 3 |
| opOperandX |
| ) |
| |
| // An jumpOp is a conditional jump condition. |
| type jumpOp uint16 |
| |
| // Supported jump conditions. |
| const ( |
| opJumpAlways jumpOp = iota << 4 |
| opJumpEqual |
| opJumpGT |
| opJumpGE |
| opJumpSet |
| ) |
| |
| const ( |
| opRetSrcConstant uint16 = iota << 4 |
| opRetSrcA |
| ) |
| |
| const ( |
| opMiscTAX = 0x00 |
| opMiscTXA = 0x80 |
| ) |