• bpf 指令集


    bpf 指令用于过滤逻辑 (filter program) 是有一个指令数组表示。

    只有向前跳转

    ret指令结束过滤

    每一个指令操作 bpf虚拟机的内部状态

    包括

    累加器:accumulator,

    指示器:index register,

    bpf内存:memory store,

    pc 程序指针: program counter.

    指令格式

    /*
     * The instruction data structure.
     */
    struct bpf_insn {
        u_short    code;    /* 16bit  这条指令做什么 */
        u_char     jt; /* jump if true  如果为真 跳转的位置 */
        u_char     jf; /* jump if false  如果为假 跳转的位置 */
        bpf_int32 k; // int
    };

    所有的指令分为8类:

    BPF_LD, BPF_LDX加载指令

    BPF_ST, BPF_STX存储指令

    BPF_ALU, 计算指令

    BPF_JMP, 跳转指令

    BPF_RET, 返回指令 (结束指令)

    BPF_MISC, 其他指令

    内存大小: BPF_MEMWORDS  ==> 16

    1) load指令

    BPF_LD 9条指令

    BPF_LD+BPF_W+BPF_ABS
    A <- P[k:4] (p是报文首地址, k是一个立即数, A 是累计器)

    BPF_LD+BPF_H+BPF_ABS
    A <- P[k:2]

    BPF_LD+BPF_B+BPF_ABS

    ldh      [12] ===> 标识加载报文的偏移12个字节的 hardword(也就是16bit) 以太网报文头 6bytes的源mac+6位目的mac 之后就是ethetype 上层协议

    ethetype: ip #800

    9c 21 6a 95 3f ac 84 34  97 94 03 ef 【08 00】 45 00 (ip 协议)

    BPF_LD+BPF_W+BPF_IND
    A <- P[X+k:4] (X 是指示器)

    BPF_LD+BPF_H+BPF_IND
    A <- P[X+k:2]

    BPF_LD+BPF_B+BPF_IND
    A <- P[X+k:1]

    BPF_LD+BPF_W+BPF_LEN
    A <- len (len是报文的长度)

    BPF_LD+BPF_IMM
    A <- k (器存器的值是 k)

    BPF_LD+BPF_MEM
    A <- M[k] (把内存的第k个字(word 4byte) 的值赋值到累加器中 )

    LDX(X = index :指示器) 4 调指令

    BPF_LDX+BPF_W+BPF_IMM
    X <- k (把k值加载到指示器)

    BPF_LDX+BPF_W+BPF_MEM
    X <- M[k] (加载内存值到指示器)

    BPF_LDX+BPF_W+BPF_LEN
    X <- len (加载报文长度到 指示器中)

    BPF_LDX+BPF_B+BPF_MSH
    X <- 4*(P[k:1]&0xf) (加载ip头部长度到指示器中)

    45 00 00 3c 47 c0 40 00 40 06  0a 95 c0 a8 01 0b 其中0x5 表示ip头长度字段 实际长度是 5*4=20byte的ip头

    BPF_ST 保存指令

    BPF_ST
    M[k] <- A 所有保存值到内存都通过 累加器 所有很简单的指令

    BPF_STX (保存指示器的值到内存中)
    M[k] <- X

    BPF_ALU

    操作数 累加器, 指示器, 常量

    BPF_ALU+BPF_ADD+BPF_K 操作立即数 k
    A <- A + k

    BPF_ALU+BPF_SUB+BPF_K
    A <- A - k

    BPF_ALU+BPF_MUL+BPF_K
    A <- A * k

    BPF_ALU+BPF_DIV+BPF_K
    A <- A / k

    BPF_ALU+BPF_AND+BPF_K
    A <- A & k

    BPF_ALU+BPF_OR+BPF_K
    A <- A | k

    BPF_ALU+BPF_LSH+BPF_K
    A <- A << k

    BPF_ALU+BPF_RSH+BPF_K
    A <- A >> k

    BPF_ALU+BPF_ADD+BPF_X 操作指示器X
    A <- A + X

    BPF_ALU+BPF_SUB+BPF_X
    A <- A - X

    BPF_ALU+BPF_MUL+BPF_X
    A <- A * X

    BPF_ALU+BPF_DIV+BPF_X
    A <- A / X

    BPF_ALU+BPF_AND+BPF_X
    A <- A & X

    BPF_ALU+BPF_OR+BPF_X
    A <- A | X

    BPF_ALU+BPF_LSH+BPF_X
    A <- A << X

    BPF_ALU+BPF_RSH+BPF_X
    A <- A >> X

    BPF_ALU+BPF_NEG 取负指令
    A <- -A

    BPF_JMP 跳转指令
    操作数是无符号的
    条件跳转 jt jf 只有8bit 最远是255的偏移
    无条件跳转可跳32bit的数

    BPF_JMP+BPF_JA
    pc += k (跳转到下k调指令处)

    BPF_JMP+BPF_JA
    pc += k

    BPF_JMP+BPF_JGT+BPF_K
    pc += (A > k) ? jt : jf

    BPF_JMP+BPF_JGE+BPF_K
    pc += (A >= k) ? jt : jf

    BPF_JMP+BPF_JEQ+BPF_K
    pc += (A == k) ? jt : jf

    BPF_JMP+BPF_JSET+BPF_K
    pc += (A & k) ? jt : jf

    BPF_JMP+BPF_JGT+BPF_X
    pc += (A > X) ? jt : jf

    BPF_JMP+BPF_JGE+BPF_X
    pc += (A >= X) ? jt : jf

    BPF_JMP+BPF_JEQ+BPF_X
    pc += (A == X) ? jt : jf

    BPF_JMP+BPF_JSET+BPF_X
    pc += (A & X) ? jt : jf

    返回指令

    如果返回0 表示忽略此报文

    BPF_RET+BPF_A
    accept A bytes

    BPF_RET+BPF_K
    accept k bytes

    BPF_MISC+BPF_TAX (t = transfer
    X <- A (累加器的值 赋给 指示器)

    BPF_MISC+BPF_TXA
    A <- X

  • 相关阅读:
    注册以及密码验证
    轮播图,渐显,可以左右点击
    节点移动
    数据持久化
    Objective-C Autorelease Pool 的实现原理(转)
    iOS应用架构谈 view层的组织和调用方案(转)
    iOS 开源项目
    iOS开发系列--无限循环的图片浏览器
    富文本常用封装(NSAttributedString浅析)(转)
    OS开发UI篇—ios应用数据存储方式(XML属性列表-plist)(转)
  • 原文地址:https://www.cnblogs.com/kwingmei/p/3629668.html
Copyright © 2020-2023  润新知