Skip to content

Commit

Permalink
Add excepts for egress to avoid SNAT (antrea-io#2707)
Browse files Browse the repository at this point in the history
Avoid SNAT for assigned IP block if the pod wants to communicate
directly, this can improve network performance

Signed-off-by: Yang Li yang.li@transwarp.io
  • Loading branch information
leonstack committed Sep 9, 2021
1 parent 589e1f7 commit 1e1676b
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 69 deletions.
8 changes: 8 additions & 0 deletions build/yamls/antrea-aks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,14 @@ spec:
- format: ipv4
- format: ipv6
type: string
excepts:
items:
properties:
cidr:
format: cidr
type: string
type: object
type: array
externalIPPool:
type: string
required:
Expand Down
8 changes: 8 additions & 0 deletions build/yamls/antrea-eks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,14 @@ spec:
- format: ipv4
- format: ipv6
type: string
excepts:
items:
properties:
cidr:
format: cidr
type: string
type: object
type: array
externalIPPool:
type: string
required:
Expand Down
8 changes: 8 additions & 0 deletions build/yamls/antrea-gke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,14 @@ spec:
- format: ipv4
- format: ipv6
type: string
excepts:
items:
properties:
cidr:
format: cidr
type: string
type: object
type: array
externalIPPool:
type: string
required:
Expand Down
8 changes: 8 additions & 0 deletions build/yamls/antrea-ipsec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,14 @@ spec:
- format: ipv4
- format: ipv6
type: string
excepts:
items:
properties:
cidr:
format: cidr
type: string
type: object
type: array
externalIPPool:
type: string
required:
Expand Down
8 changes: 8 additions & 0 deletions build/yamls/antrea.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,14 @@ spec:
- format: ipv4
- format: ipv6
type: string
excepts:
items:
properties:
cidr:
format: cidr
type: string
type: object
type: array
externalIPPool:
type: string
required:
Expand Down
8 changes: 8 additions & 0 deletions build/yamls/base/crds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ spec:
oneOf:
- format: ipv4
- format: ipv6
excepts:
items:
properties:
cidr:
type: string
format: cidr
type: object
type: array
externalIPPool:
type: string
status:
Expand Down
27 changes: 23 additions & 4 deletions pkg/agent/controller/egress/egress_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"net"
"reflect"
"sort"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -81,6 +82,8 @@ type egressState struct {
egressIP string
// The actual datapath mark of this Egress. Used to check if the mark changes since last process.
mark uint32
// The except Info for bypass SNAT flows
excepts []crdv1a2.Except
// The actual openflow ports for which we have installed SNAT rules. Used to identify stale openflow ports when
// updating or deleting an Egress.
ofPorts sets.Int32
Expand Down Expand Up @@ -464,11 +467,12 @@ func (c *EgressController) deleteEgressState(egressName string) {
delete(c.egressStates, egressName)
}

func (c *EgressController) newEgressState(egressName string, egressIP string) *egressState {
func (c *EgressController) newEgressState(egressName string, egressIP string, excepts []crdv1a2.Except) *egressState {
c.egressStatesMutex.Lock()
defer c.egressStatesMutex.Unlock()
state := &egressState{
egressIP: egressIP,
excepts: excepts,
ofPorts: sets.NewInt32(),
pods: sets.NewString(),
}
Expand Down Expand Up @@ -592,7 +596,7 @@ func (c *EgressController) syncEgress(egressName string) error {
return nil
}
if !exist {
eState = c.newEgressState(egressName, egress.Spec.EgressIP)
eState = c.newEgressState(egressName, egress.Spec.EgressIP, egress.Spec.Excepts)
}

localNodeSelected, err := c.cluster.ShouldSelectEgress(egress)
Expand All @@ -619,12 +623,13 @@ func (c *EgressController) syncEgress(egressName string) error {

// If the mark changes, uninstall all of the Egress's Pod flows first, then installs them with new mark.
// It could happen when the Egress IP is added to or removed from the Node.
if eState.mark != mark {
if eState.mark != mark || !Equal(eState.excepts, egress.Spec.Excepts) {
// Uninstall all of its Pod flows.
if err := c.uninstallPodFlows(egressName, eState, eState.ofPorts, eState.pods); err != nil {
return err
}
eState.mark = mark
eState.excepts = egress.Spec.Excepts
}

if err := c.updateEgressStatus(egress, c.localIPDetector.IsLocalIP(egress.Spec.EgressIP)); err != nil {
Expand Down Expand Up @@ -671,7 +676,7 @@ func (c *EgressController) syncEgress(egressName string) error {
staleOFPorts.Delete(ofPort)
continue
}
if err := c.ofClient.InstallPodSNATFlows(uint32(ofPort), egressIP, mark); err != nil {
if err := c.ofClient.InstallPodSNATFlows(uint32(ofPort), egressIP, mark, eState.excepts); err != nil {
return err
}
eState.ofPorts.Insert(ofPort)
Expand Down Expand Up @@ -872,3 +877,17 @@ func (c *EgressController) deleteEgressGroup(group *cpv1b2.EgressGroup) {
delete(c.egressGroups, group.Name)
c.queue.Add(group.Name)
}

func Equal(a, b []crdv1a2.Except) bool {
if len(a) != len(b) {
return false
}
sort.Slice(a, func(i, j int) bool {return a[i].CIDR < a[j].CIDR})
sort.Slice(b, func(i, j int) bool {return b[i].CIDR < b[j].CIDR})
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}
Loading

0 comments on commit 1e1676b

Please sign in to comment.