constants.go 6.04 KB
Newer Older
zhangweiwei's avatar
init  
zhangweiwei committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
// 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
)