github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/overlay/bpf.go (about) 1 package overlay 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "golang.org/x/net/bpf" 9 ) 10 11 // vniMatchBPF returns a BPF program suitable for passing to the iptables and 12 // ip6tables bpf match which matches on the VXAN Network ID of encapsulated 13 // packets. The program assumes that it will be used in a rule which only 14 // matches UDP datagrams. 15 func vniMatchBPF(vni uint32) []bpf.RawInstruction { 16 asm, err := bpf.Assemble([]bpf.Instruction{ 17 // Load offset of UDP payload into X. 18 bpf.LoadExtension{Num: bpf.ExtPayloadOffset}, // ld poff 19 bpf.TAX{}, // tax 20 21 bpf.LoadIndirect{Off: 4, Size: 4}, // ld [x + 4] ; Load VXLAN ID into top 24 bits of A 22 bpf.ALUOpConstant{Op: bpf.ALUOpShiftRight, Val: 8}, // rsh #8 ; A >>= 8 23 bpf.JumpIf{Cond: bpf.JumpEqual, Val: vni, SkipTrue: 1}, // jeq $vni, match 24 bpf.RetConstant{Val: 0}, // ret #0 25 bpf.RetConstant{Val: ^uint32(0)}, // match: ret #-1 26 }) 27 // bpf.Assemble() only errors if an instruction is invalid. As the only variable 28 // part of the program is an instruction value for which the entire range is 29 // valid, whether the program can be successfully assembled is independent of 30 // the input. Given that the only recourse is to fix this function and 31 // recompile, there's little value in bubbling the error up to the caller. 32 if err != nil { 33 panic(err) 34 } 35 return asm 36 } 37 38 // marshalXTBPF marshals a BPF program into the "decimal" byte code format 39 // which is suitable for passing to the [iptables bpf match]. 40 // 41 // iptables -m bpf --bytecode 42 // 43 // [iptables bpf match]: https://ipset.netfilter.org/iptables-extensions.man.html#lbAH 44 func marshalXTBPF(prog []bpf.RawInstruction) string { //nolint:unused 45 var b strings.Builder 46 fmt.Fprintf(&b, "%d", len(prog)) 47 for _, ins := range prog { 48 fmt.Fprintf(&b, ",%d %d %d %d", ins.Op, ins.Jt, ins.Jf, ins.K) 49 } 50 return b.String() 51 } 52 53 // matchVXLAN returns an iptables rule fragment which matches VXLAN datagrams 54 // with the given destination port and VXLAN Network ID utilizing the xt_bpf 55 // netfilter kernel module. The returned slice's backing array is guaranteed not 56 // to alias any other slice's. 57 func matchVXLAN(port, vni uint32) []string { 58 dport := strconv.FormatUint(uint64(port), 10) 59 vniMatch := marshalXTBPF(vniMatchBPF(vni)) 60 61 // https://ipset.netfilter.org/iptables-extensions.man.html#lbAH 62 return []string{"-p", "udp", "--dport", dport, "-m", "bpf", "--bytecode", vniMatch} 63 }