読者です 読者をやめる 読者になる 読者になる

Packets are too Fast

slankdevの報告

cBPF命令セット

ここでは単純に表と図のみでcBPFにどのような命令が含まれて、 どのように動作するのかを示す。Instruction set archの設計論などは まったく触れない。 (ただつかう段階では必要ないため。) 必要があれば、それぞれのBitにどのような意味があるかも説明していく。

Encoding

struct cbpf_insn {
    uint16_t opcode;
    uint8_t  jt;
    uint8_t  jf;
    uint32_t k;
};
    msb                                                        lsb
    +------------------------+--------+--------+----------------+
    |           k            |   jf   |   jt   |     opcode     |
    +------------------------+--------+--------+----------------+

Instruction Classは以下の3つに分類できる.

  • ALU
  • Memory Access
  • Branch
  • Misc

ALU

Opcode Mnemonic Pseudocode
0x0004 add k A+=k
0x0014 sub k A-=k
0x0024 mul k A*=k
0x0054 and k A&=k
0x0044 or k A|=k
0x0034 div k A/=k
0x0064 lsh k A<<=k
0x0074 rsh k A>>=k
0x000c add x A+=X
0x001c sub x A-=X
0x002c mul x A*=X
0x004c or x A|=X
0x003c div x A/=X
0x005c and x A&=X
0x006c lsh x A<<=X
0x007c rsh x A>>=X
0x0084 neg A=-A

Memory Access

Opcode Mnemonic Pseudocode
0x0000 ld k A = k
0x0001 ldx k X = k
0x0002 st M[k] mem[k] = A
0x0003 stx M[k] mem[k] = X
0x0020 ld [k] A = ntohl((i32)(p+k))
0x0028 ldh [k] A = short(&p[k])
0x0030 ldb [k] A = p[k]
0x0040 ld [k] A = ntohl((i32)(p+k))
0x0048 ldh [k] A = short(&p[k])
0x0050 ldb [k] A = p[k]
0x0060 ld M[k] A = mem[k]
0x0061 ldx M[k] X = mem[k]
0x0080 ld #pktlen A = wirelen
0x0081 (n/a) X = wirelen
0x00b1 ldxb 4*([k]&0xf) X = (p[k]&0xf)<<2

Branch

Opcode Mnemonic Pseudocode
0x0005 ja k pc+=k
0x0015 jeq k jt jf pc+=(A==k)?jt:jf
0x0025 jgt k jt jf pc+=(A>k)?jt:jf
0x0035 jge k jt jf pc+=(A>=k)?jt:jf
0x0045 jset k jt jf pc+=(A&k)?jt:jf
0x003d jge x jt jt pc+=(A>=X)?jt:jf
0x001d jeq x jt jt pc+=(A==X)?jt:jf
0x002d jgt x jt jf pc+=(A>X)?jt:jf
0x004d jset x jt jt pc+=(A&X)?jt:jf
0x0006 ret k return k
0x0016 ret return A

Misc

Opcode Mnemonic Pseudocode
0x0087 txa A=X
0x0007 tax X=A

Reference