github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/libnetwork/drivers/overlay/bpf.go (about) 1 package overlay 2 3 import ( 4 "fmt" 5 "strings" 6 7 "golang.org/x/net/bpf" 8 ) 9 10 // vniMatchBPF returns a BPF program suitable for passing to the iptables bpf 11 // match which matches on the VXAN Network ID of encapsulated packets. The 12 // program assumes that it will be used in a rule which only matches UDP 13 // datagrams. 14 func vniMatchBPF(vni uint32) []bpf.RawInstruction { 15 asm, err := bpf.Assemble([]bpf.Instruction{ 16 bpf.LoadMemShift{Off: 0}, // ldx 4*([0] & 0xf) ; Load length of IPv4 header into X 17 bpf.LoadIndirect{Off: 12, Size: 4}, // ld [x + 12] ; Load VXLAN ID (UDP header + 4 bytes) into A 18 bpf.ALUOpConstant{Op: bpf.ALUOpAnd, Val: 0xffffff00}, // and #0xffffff00 ; VXLAN ID is in top 24 bits 19 bpf.JumpIf{Cond: bpf.JumpEqual, Val: vni << 8, SkipTrue: 1}, // jeq ($vni << 8), match 20 bpf.RetConstant{Val: 0}, // ret #0 21 bpf.RetConstant{Val: ^uint32(0)}, // match: ret #-1 22 }) 23 // bpf.Assemble() only errors if an instruction is invalid. As the only variable 24 // part of the program is an instruction value for which the entire range is 25 // valid, whether the program can be successfully assembled is independent of 26 // the input. Given that the only recourse is to fix this function and 27 // recompile, there's little value in bubbling the error up to the caller. 28 if err != nil { 29 panic(err) 30 } 31 return asm 32 } 33 34 // marshalXTBPF marshals a BPF program into the "decimal" byte code format 35 // which is suitable for passing to the [iptables bpf match]. 36 // 37 // iptables -m bpf --bytecode 38 // 39 // [iptables bpf match]: https://ipset.netfilter.org/iptables-extensions.man.html#lbAH 40 func marshalXTBPF(prog []bpf.RawInstruction) string { //nolint:unused 41 var b strings.Builder 42 fmt.Fprintf(&b, "%d", len(prog)) 43 for _, ins := range prog { 44 fmt.Fprintf(&b, ",%d %d %d %d", ins.Op, ins.Jt, ins.Jf, ins.K) 45 } 46 return b.String() 47 }