libn/d/overlay: make VNI matcher IPv6-compatible
Use Linux BPF extensions to locate the offset of the VXLAN header within the packet so that the same BPF program works with VXLAN packets received over either IPv4 or IPv6. Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
parent
7d9bb170b7
commit
c399963243
1 changed files with 13 additions and 10 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue