Skip to content

Commit

Permalink
Multiple ExGW: fixes unique pod exgw cache key
Browse files Browse the repository at this point in the history
When pods are added to the cache as exgws for a namespace, only the
pod's name is used as the key. This breaks a scenario where 2 pods with
the same name are serving as exgws for the same namespace. Consider this
example:

1. app pod is created in ns foo
2. exgwAPod is created in ns exgw1 (172.0.1.1), serving ns foo
3. exgwAPod is created in ns exgw2 (172.0.1.2), serving ns foo

In the above example, the app pod will only have one ECMP route for
172.0.1.2, because the cache is keyed only on pod name.

Signed-off-by: Tim Rozet <trozet@redhat.com>
  • Loading branch information
trozet committed Jan 7, 2022
1 parent dd6fe83 commit a801777
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
15 changes: 10 additions & 5 deletions go-controller/pkg/ovn/egressgw.go
Expand Up @@ -197,7 +197,7 @@ func (oc *Controller) addPodExternalGWForNamespace(namespace string, pod *kapi.P
pod.Namespace, pod.Name, namespace, err)
}

nsInfo.routingExternalPodGWs[pod.Name] = egress
nsInfo.routingExternalPodGWs[makePodGWKey(pod)] = egress
nsUnlock()

klog.Infof("Adding routes for external gateway pod: %s, next hops: %q, namespace: %s, bfd-enabled: %t",
Expand Down Expand Up @@ -351,19 +351,20 @@ func (oc *Controller) deletePodExternalGW(pod *kapi.Pod) {
klog.Infof("Deleting routes for external gateway pod: %s, for namespace(s) %s", pod.Name,
podRoutingNamespaceAnno)
for _, namespace := range strings.Split(podRoutingNamespaceAnno, ",") {
oc.deletePodGWRoutesForNamespace(pod.Name, namespace)
oc.deletePodGWRoutesForNamespace(pod, namespace)
}
}

// deletePodGwRoutesForNamespace handles deleting all routes in a namespace for a specific pod GW
func (oc *Controller) deletePodGWRoutesForNamespace(pod, namespace string) {
func (oc *Controller) deletePodGWRoutesForNamespace(pod *kapi.Pod, namespace string) {
nsInfo, nsUnlock := oc.getNamespaceLocked(namespace, false)
if nsInfo == nil {
return
}
podGWKey := makePodGWKey(pod)
// check if any gateways were stored for this pod
foundGws, ok := nsInfo.routingExternalPodGWs[pod]
delete(nsInfo.routingExternalPodGWs, pod)
foundGws, ok := nsInfo.routingExternalPodGWs[podGWKey]
delete(nsInfo.routingExternalPodGWs, podGWKey)
nsUnlock()

if !ok || len(foundGws.gws) == 0 {
Expand Down Expand Up @@ -1250,3 +1251,7 @@ func (oc *Controller) buildOVNECMPCache() map[string][]*ovnRoute {
}
return ovnRouteCache
}

func makePodGWKey(pod *kapi.Pod) string {
return fmt.Sprintf("%s_%s", pod.Namespace, pod.Name)
}
1 change: 1 addition & 0 deletions go-controller/pkg/ovn/ovn.go
Expand Up @@ -89,6 +89,7 @@ type namespaceInfo struct {

// routingExternalPodGWs contains a map of all pods serving as exgws as well as their
// exgw IPs
// key is <namespace>_<pod name>
routingExternalPodGWs map[string]gatewayInfo

multicastEnabled bool
Expand Down

0 comments on commit a801777

Please sign in to comment.