From aa716033320f285a6c1ef4373eed006b4d2da792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=A5=96=E5=BB=BA?= Date: Sun, 9 Oct 2022 09:56:22 +0800 Subject: [PATCH] ovs: fix mac learning in environments with hairpin enabled (#1943) --- dist/images/Dockerfile.base | 2 ++ pkg/daemon/config.go | 3 +++ pkg/daemon/controller.go | 2 +- pkg/daemon/init.go | 4 ++-- pkg/daemon/ovs.go | 3 ++- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/dist/images/Dockerfile.base b/dist/images/Dockerfile.base index 2a1564e2bca..8d0d06abff5 100644 --- a/dist/images/Dockerfile.base +++ b/dist/images/Dockerfile.base @@ -24,6 +24,8 @@ RUN cd /usr/src/ && \ curl -s https://github.com/kubeovn/ovs/commit/22ea22c40b46ee5adeae977ff6cfca81b3ff25d7.patch | git apply && \ # add fdb update logging curl -s https://github.com/kubeovn/ovs/commit/8c2f28b778129161bbf8f0738fa41d385860d5bc.patch | git apply && \ + # fdb: fix mac learning in environments with hairpin enabled + curl -s https://github.com/kubeovn/ovs/commit/1cb138aaf2fdf922d75a587e4e9cf610d38f9fee.patch | git apply && \ # compile without avx512 if [ "$ARCH" = "amd64" -a "$NO_AVX512" = "true" ]; then curl -s https://github.com/kubeovn/ovs/commit/c257b0794b827cfae9660a9f3238bee8a29e7676.patch | git apply; fi && \ ./boot.sh && \ diff --git a/pkg/daemon/config.go b/pkg/daemon/config.go index 57c35df91f4..d360e310372 100644 --- a/pkg/daemon/config.go +++ b/pkg/daemon/config.go @@ -46,6 +46,7 @@ type Configuration struct { NodeLocalDnsIP string EncapChecksum bool EnablePprof bool + MacLearningFallback bool PprofPort int NetworkType string CniConfDir string @@ -74,6 +75,7 @@ func ParseFlags() *Configuration { argEncapChecksum = pflag.Bool("encap-checksum", true, "Enable checksum") argEnablePprof = pflag.Bool("enable-pprof", false, "Enable pprof") argPprofPort = pflag.Int("pprof-port", 10665, "The port to get profiling data") + argMacLearningFallback = pflag.Bool("mac-learning-fallback", false, "Fallback to the legacy MAC learning mode") argsNetworkType = pflag.String("network-type", util.NetworkTypeGeneve, "Tunnel encapsulation protocol in overlay networks") argCniConfDir = pflag.String("cni-conf-dir", "/etc/cni/net.d", "Path of the CNI config directory.") @@ -116,6 +118,7 @@ func ParseFlags() *Configuration { KubeConfigFile: *argKubeConfigFile, EnablePprof: *argEnablePprof, PprofPort: *argPprofPort, + MacLearningFallback: *argMacLearningFallback, NodeName: strings.ToLower(*argNodeName), ServiceClusterIPRange: *argServiceClusterIPRange, NodeLocalDnsIP: *argNodeLocalDnsIP, diff --git a/pkg/daemon/controller.go b/pkg/daemon/controller.go index 7360f5c274b..e1b28a87070 100644 --- a/pkg/daemon/controller.go +++ b/pkg/daemon/controller.go @@ -264,7 +264,7 @@ func (c *Controller) initProviderNetwork(pn *kubeovnv1.ProviderNetwork, node *v1 var mtu int var err error - if mtu, err = ovsInitProviderNetwork(pn.Name, nic, pn.Spec.ExchangeLinkName); err != nil { + if mtu, err = ovsInitProviderNetwork(pn.Name, nic, pn.Spec.ExchangeLinkName, c.config.MacLearningFallback); err != nil { if oldLen := len(node.Labels); oldLen != 0 { delete(node.Labels, fmt.Sprintf(util.ProviderNetworkReadyTemplate, pn.Name)) delete(node.Labels, fmt.Sprintf(util.ProviderNetworkInterfaceTemplate, pn.Name)) diff --git a/pkg/daemon/init.go b/pkg/daemon/init.go index 42997f8aa5b..d304d475906 100644 --- a/pkg/daemon/init.go +++ b/pkg/daemon/init.go @@ -96,7 +96,7 @@ func InitMirror(config *Configuration) error { return configureEmptyMirror(config.MirrorNic, config.MTU) } -func ovsInitProviderNetwork(provider, nic string, exchangeLinkName bool) (int, error) { +func ovsInitProviderNetwork(provider, nic string, exchangeLinkName, macLearningFallback bool) (int, error) { // create and configure external bridge brName := util.ExternalBridgeName(provider) if exchangeLinkName { @@ -110,7 +110,7 @@ func ovsInitProviderNetwork(provider, nic string, exchangeLinkName bool) (int, e } } - if err := configExternalBridge(provider, brName, nic, exchangeLinkName); err != nil { + if err := configExternalBridge(provider, brName, nic, exchangeLinkName, macLearningFallback); err != nil { errMsg := fmt.Errorf("failed to create and configure external bridge %s: %v", brName, err) klog.Error(errMsg) return 0, errMsg diff --git a/pkg/daemon/ovs.go b/pkg/daemon/ovs.go index a6f04d8f02c..577fb995dc3 100644 --- a/pkg/daemon/ovs.go +++ b/pkg/daemon/ovs.go @@ -71,12 +71,13 @@ func configureEmptyMirror(portName string, mtu int) error { return configureMirrorLink(portName, mtu) } -func configExternalBridge(provider, bridge, nic string, exchangeLinkName bool) error { +func configExternalBridge(provider, bridge, nic string, exchangeLinkName, macLearningFallback bool) error { brExists, err := ovs.BridgeExists(bridge) if err != nil { return fmt.Errorf("failed to check OVS bridge existence: %v", err) } output, err := ovs.Exec(ovs.MayExist, "add-br", bridge, + "--", "set", "bridge", bridge, fmt.Sprintf("other_config:mac-learning-fallback=%v", macLearningFallback), "--", "set", "bridge", bridge, "external_ids:vendor="+util.CniTypeName, "--", "set", "bridge", bridge, fmt.Sprintf("external_ids:exchange-link-name=%v", exchangeLinkName), )