diff --git a/libnetwork/drivers/overlay/bpf.go b/libnetwork/drivers/overlay/bpf.go index 093b4950b8..4bb07f06e5 100644 --- a/libnetwork/drivers/overlay/bpf.go +++ b/libnetwork/drivers/overlay/bpf.go @@ -8,18 +8,21 @@ import ( "golang.org/x/net/bpf" ) -// vniMatchBPF returns a BPF program suitable for passing to the iptables bpf -// match which matches on the VXAN Network ID of encapsulated packets. The -// program assumes that it will be used in a rule which only matches UDP -// datagrams. +// vniMatchBPF returns a BPF program suitable for passing to the iptables and +// ip6tables bpf match which matches on the VXAN Network ID of encapsulated +// packets. The program assumes that it will be used in a rule which only +// matches UDP datagrams. func vniMatchBPF(vni uint32) []bpf.RawInstruction { asm, err := bpf.Assemble([]bpf.Instruction{ - bpf.LoadMemShift{Off: 0}, // ldx 4*([0] & 0xf) ; Load length of IPv4 header into X - bpf.LoadIndirect{Off: 12, Size: 4}, // ld [x + 12] ; Load VXLAN ID (UDP header + 4 bytes) into A - bpf.ALUOpConstant{Op: bpf.ALUOpAnd, Val: 0xffffff00}, // and #0xffffff00 ; VXLAN ID is in top 24 bits - bpf.JumpIf{Cond: bpf.JumpEqual, Val: vni << 8, SkipTrue: 1}, // jeq ($vni << 8), match - bpf.RetConstant{Val: 0}, // ret #0 - bpf.RetConstant{Val: ^uint32(0)}, // match: ret #-1 + // Load offset of UDP payload into X. + bpf.LoadExtension{Num: bpf.ExtPayloadOffset}, // ld poff + bpf.TAX{}, // tax + + bpf.LoadIndirect{Off: 4, Size: 4}, // ld [x + 4] ; Load VXLAN ID into top 24 bits of A + bpf.ALUOpConstant{Op: bpf.ALUOpShiftRight, Val: 8}, // rsh #8 ; A >>= 8 + bpf.JumpIf{Cond: bpf.JumpEqual, Val: vni, SkipTrue: 1}, // jeq $vni, match + bpf.RetConstant{Val: 0}, // ret #0 + bpf.RetConstant{Val: ^uint32(0)}, // match: ret #-1 }) // bpf.Assemble() only errors if an instruction is invalid. As the only variable // part of the program is an instruction value for which the entire range is