Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a393fab

Browse files
author
Ravi Sankar Penta
committedApr 13, 2018
Modify UpdateEgressNetworkPolicyRules() to use ovs.Bundle() to avoid races and reduce downtime
1 parent ab8207c commit a393fab

File tree

1 file changed

+21
-28
lines changed

1 file changed

+21
-28
lines changed
 

‎pkg/network/node/ovscontroller.go

+21-28
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/openshift/origin/pkg/network/common"
1717
"github.com/openshift/origin/pkg/util/ovs"
1818

19+
kerrs "k8s.io/apimachinery/pkg/util/errors"
1920
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2021
"k8s.io/apimachinery/pkg/util/sets"
2122
kapi "k8s.io/kubernetes/pkg/apis/core"
@@ -424,28 +425,29 @@ func policyNames(policies []networkapi.EgressNetworkPolicy) string {
424425
}
425426

426427
func (oc *ovsController) UpdateEgressNetworkPolicyRules(policies []networkapi.EgressNetworkPolicy, vnid uint32, namespaces []string, egressDNS *common.EgressDNS) error {
427-
otx := oc.ovs.NewTransaction()
428-
var inputErr error
428+
var flows []string
429+
var errs []error
429430

430431
if len(policies) == 0 {
431-
otx.DeleteFlows("table=101, reg0=%d", vnid)
432+
flows = append(flows, ovs.BundleDeleteFlowRepr("table=101, reg0=%d", vnid))
432433
} else if vnid == 0 {
433-
inputErr = fmt.Errorf("EgressNetworkPolicy in global network namespace is not allowed (%s); ignoring", policyNames(policies))
434+
errs = append(errs, fmt.Errorf("EgressNetworkPolicy in global network namespace is not allowed (%s); ignoring", policyNames(policies)))
434435
} else if len(namespaces) > 1 {
435436
// Rationale: In our current implementation, multiple namespaces share their network by using the same VNID.
436437
// Even though Egress network policy is defined per namespace, its implementation is based on VNIDs.
437438
// So in case of shared network namespaces, egress policy of one namespace will affect all other namespaces that are sharing the network which might not be desirable.
438-
inputErr = fmt.Errorf("EgressNetworkPolicy not allowed in shared NetNamespace (%s); dropping all traffic", strings.Join(namespaces, ", "))
439-
otx.DeleteFlows("table=101, reg0=%d", vnid)
440-
otx.AddFlow("table=101, reg0=%d, priority=1, actions=drop", vnid)
439+
errs = append(errs, fmt.Errorf("EgressNetworkPolicy not allowed in shared NetNamespace (%s); dropping all traffic", strings.Join(namespaces, ", ")))
440+
flows = append(flows, ovs.BundleDeleteFlowRepr("table=101, reg0=%d", vnid))
441+
flows = append(flows, ovs.BundleAddFlowRepr("table=101, reg0=%d, priority=1, actions=drop", vnid))
441442
} else if len(policies) > 1 {
442443
// Rationale: If we have allowed more than one policy, we could end up with different network restrictions depending
443444
// on the order of policies that were processed and also it doesn't give more expressive power than a single policy.
444-
inputErr = fmt.Errorf("multiple EgressNetworkPolicies in same network namespace (%s) is not allowed; dropping all traffic", policyNames(policies))
445-
otx.DeleteFlows("table=101, reg0=%d", vnid)
446-
otx.AddFlow("table=101, reg0=%d, priority=1, actions=drop", vnid)
445+
errs = append(errs, fmt.Errorf("multiple EgressNetworkPolicies in same network namespace (%s) is not allowed; dropping all traffic", policyNames(policies)))
446+
flows = append(flows, ovs.BundleDeleteFlowRepr("table=101, reg0=%d", vnid))
447+
flows = append(flows, ovs.BundleAddFlowRepr("table=101, reg0=%d, priority=1, actions=drop", vnid))
447448
} else /* vnid != 0 && len(policies) == 1 */ {
448-
var flows []string
449+
flows = append(flows, ovs.BundleDeleteFlowRepr("table=101, reg0=%d", vnid))
450+
449451
dnsFound := false
450452
for i, rule := range policies[0].Spec.Egress {
451453
priority := len(policies[0].Spec.Egress) - i
@@ -479,33 +481,24 @@ func (oc *ovsController) UpdateEgressNetworkPolicyRules(policies []networkapi.Eg
479481
dst = fmt.Sprintf(", nw_dst=%s", selector)
480482
}
481483

482-
flows = append(flows, fmt.Sprintf("table=101, reg0=%d, priority=%d, ip%s, actions=%s", vnid, priority, dst, action))
484+
flows = append(flows, ovs.BundleAddFlowRepr("table=101, reg0=%d, priority=%d, ip%s, actions=%s", vnid, priority, dst, action))
483485
}
484486
}
485487

486-
// Temporarily drop all outgoing traffic, to avoid race conditions while modifying the other rules
487-
otx.AddFlow("table=101, reg0=%d, cookie=1, priority=65535, actions=drop", vnid)
488-
otx.DeleteFlows("table=101, reg0=%d, cookie=0/1", vnid)
489-
for _, f := range flows {
490-
otx.AddFlow(f)
491-
}
492-
493488
if dnsFound {
494489
if err := common.CheckDNSResolver(); err != nil {
495-
inputErr = fmt.Errorf("DNS resolver failed: %v, dropping all traffic for namespace: %q", err, namespaces[0])
496-
otx.DeleteFlows("table=101, reg0=%d", vnid)
497-
otx.AddFlow("table=101, reg0=%d, priority=1, actions=drop", vnid)
490+
errs = append(errs, fmt.Errorf("DNS resolver failed: %v, dropping all traffic for namespace: %q", err, namespaces[0]))
491+
flows = []string{ovs.BundleDeleteFlowRepr("table=101, reg0=%d", vnid)}
492+
flows = append(flows, ovs.BundleAddFlowRepr("table=101, reg0=%d, priority=1, actions=drop", vnid))
498493
}
499494
}
500-
otx.DeleteFlows("table=101, reg0=%d, cookie=1/1", vnid)
501495
}
502496

503-
txErr := otx.EndTransaction()
504-
if inputErr != nil {
505-
return inputErr
506-
} else {
507-
return txErr
497+
if err := oc.ovs.Bundle(flows); err != nil {
498+
errs = append(errs, err)
508499
}
500+
501+
return kerrs.NewAggregate(errs)
509502
}
510503

511504
func hostSubnetCookie(subnet *networkapi.HostSubnet) uint32 {

0 commit comments

Comments
 (0)
Please sign in to comment.