Merge pull request #45281 from corhere/libnet/overlay-bpf-harder
libnetwork/drivers/overlay: only program xt_bpf rules
This commit is contained in:
commit
1bdceb8a65
4 changed files with 17 additions and 76 deletions
|
@ -2,6 +2,7 @@ package overlay
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
|
@ -45,3 +46,15 @@ func marshalXTBPF(prog []bpf.RawInstruction) string { //nolint:unused
|
|||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// matchVXLAN returns an iptables rule fragment which matches VXLAN datagrams
|
||||
// with the given destination port and VXLAN Network ID utilizing the xt_bpf
|
||||
// netfilter kernel module. The returned slice's backing array is guaranteed not
|
||||
// to alias any other slice's.
|
||||
func matchVXLAN(port, vni uint32) []string {
|
||||
dport := strconv.FormatUint(uint64(port), 10)
|
||||
vniMatch := marshalXTBPF(vniMatchBPF(vni))
|
||||
|
||||
// https://ipset.netfilter.org/iptables-extensions.man.html#lbAH
|
||||
return []string{"-p", "udp", "--dport", dport, "-m", "bpf", "--bytecode", vniMatch}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/docker/docker/libnetwork/iptables"
|
||||
"github.com/docker/docker/libnetwork/ns"
|
||||
"github.com/docker/docker/libnetwork/types"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
@ -226,31 +225,7 @@ func removeEncryption(localIP, remoteIP net.IP, em *encrMap) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type matchVXLANFunc func(port, vni uint32) []string
|
||||
|
||||
// programVXLANRuleFunc returns a function which tries calling programWithMatch
|
||||
// with the u32 match, falling back to the BPF match if installing u32 variant
|
||||
// of the rules fails.
|
||||
func programVXLANRuleFunc(programWithMatch func(matchVXLAN matchVXLANFunc, vni uint32, add bool) error) func(vni uint32, add bool) error {
|
||||
return func(vni uint32, add bool) error {
|
||||
if add {
|
||||
if err := programWithMatch(matchVXLANWithU32, vni, add); err != nil {
|
||||
// That didn't work. Maybe the xt_u32 module isn't available? Try again with xt_bpf.
|
||||
err2 := programWithMatch(matchVXLANWithBPF, vni, add)
|
||||
if err2 != nil {
|
||||
return multierror.Append(err, err2)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
// Delete both flavours.
|
||||
err := programWithMatch(matchVXLANWithU32, vni, add)
|
||||
return multierror.Append(err, programWithMatch(matchVXLANWithBPF, vni, add)).ErrorOrNil()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var programMangle = programVXLANRuleFunc(func(matchVXLAN matchVXLANFunc, vni uint32, add bool) error {
|
||||
func programMangle(vni uint32, add bool) error {
|
||||
var (
|
||||
m = strconv.FormatUint(mark, 10)
|
||||
chain = "OUTPUT"
|
||||
|
@ -272,9 +247,9 @@ var programMangle = programVXLANRuleFunc(func(matchVXLAN matchVXLANFunc, vni uin
|
|||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var programInput = programVXLANRuleFunc(func(matchVXLAN matchVXLANFunc, vni uint32, add bool) error {
|
||||
func programInput(vni uint32, add bool) error {
|
||||
var (
|
||||
plainVxlan = matchVXLAN(overlayutils.VXLANUDPPort(), vni)
|
||||
chain = "INPUT"
|
||||
|
@ -315,7 +290,7 @@ var programInput = programVXLANRuleFunc(func(matchVXLAN matchVXLANFunc, vni uint
|
|||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func programSA(localIP, remoteIP net.IP, spi *spi, k *key, dir int, add bool) (fSA *netlink.XfrmState, rSA *netlink.XfrmState, err error) {
|
||||
var (
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package overlay
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// matchVXLANWithBPF returns an iptables rule fragment which matches VXLAN
|
||||
// datagrams with the given destination port and VXLAN Network ID utilizing the
|
||||
// xt_bpf netfilter kernel module. The returned slice's backing array is
|
||||
// guaranteed not to alias any other slice's.
|
||||
func matchVXLANWithBPF(port, vni uint32) []string {
|
||||
dport := strconv.FormatUint(uint64(port), 10)
|
||||
vniMatch := marshalXTBPF(vniMatchBPF(vni))
|
||||
|
||||
// https://ipset.netfilter.org/iptables-extensions.man.html#lbAH
|
||||
return []string{"-p", "udp", "--dport", dport, "-m", "bpf", "--bytecode", vniMatch}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package overlay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// matchVXLANWithU32 returns an iptables rule fragment which matches VXLAN
|
||||
// datagrams with the given destination port and VXLAN Network ID utilizing the
|
||||
// xt_u32 netfilter kernel module. The returned slice's backing array is
|
||||
// guaranteed not to alias any other slice's.
|
||||
func matchVXLANWithU32(port, vni uint32) []string {
|
||||
dport := strconv.FormatUint(uint64(port), 10)
|
||||
|
||||
// The u32 expression language is documented in iptables-extensions(8).
|
||||
// https://ipset.netfilter.org/iptables-extensions.man.html#lbCK
|
||||
//
|
||||
// 0>>22&0x3C ; Compute number of octets in IPv4 header
|
||||
// @ ; Make this the new offset into the packet
|
||||
// ; (jump to start of UDP header)
|
||||
// 12&0xFFFFFF00 ; Read 32-bit value at offset 12 and mask off the bottom octet
|
||||
// = ; Test whether the value is equal to a constant
|
||||
//
|
||||
// A UDP header is eight octets long so offset 12 from the start of the
|
||||
// UDP header is four octets into the payload: the VNI field of the
|
||||
// VXLAN header.
|
||||
vniMatch := fmt.Sprintf("0>>22&0x3C@12&0xFFFFFF00=%d", int(vni)<<8)
|
||||
|
||||
return []string{"-p", "udp", "--dport", dport, "-m", "u32", "--u32", vniMatch}
|
||||
}
|
Loading…
Add table
Reference in a new issue