Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v1.9] pkg/datapath/linux: Fix asymmetric IPsec logic on delete #18847

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 21 additions & 34 deletions pkg/datapath/linux/node.go
Expand Up @@ -1054,7 +1054,9 @@ func (n *linuxNodeHandler) nodeDelete(oldNode *nodeTypes.Node) error {
}

if n.nodeConfig.EnableIPSec {
n.deleteIPsec(oldNode)
if oldNode.IsLocal() || !n.subnetEncryption() {
n.deleteIPsec(oldNode)
}
}

return nil
Expand Down Expand Up @@ -1200,13 +1202,10 @@ func (n *linuxNodeHandler) createNodeExternalIPSecOutRoute(ip *net.IPNet, dflt b
}
}

// replaceNodeIPSecOutRoute replace the out IPSec route in the host routing table
// with the new route. If no route exists the route is installed on the host.
// replaceNodeIPSecOutRoute replace the out IPSec route in the host routing
// table with the new route. If no route exists the route is installed on the
// host. The caller must ensure that the CIDR passed in must be non-nil.
func (n *linuxNodeHandler) replaceNodeIPSecOutRoute(ip *net.IPNet) {
if ip == nil {
return
}

if ip.IP.To4() != nil {
if !n.nodeConfig.EnableIPv4 {
return
Expand All @@ -1219,17 +1218,14 @@ func (n *linuxNodeHandler) replaceNodeIPSecOutRoute(ip *net.IPNet) {

_, err := route.Upsert(n.createNodeIPSecOutRoute(ip))
if err != nil {
log.WithError(err).Error("Unable to replace the IPSec route OUT the host routing table")
log.WithError(err).WithField(logfields.CIDR, ip).Error("Unable to replace the IPSec route OUT the host routing table")
}
}

// replaceNodeExternalIPSecOutRoute replace the out IPSec route in the host routing table
// with the new route. If no route exists the route is installed on the host.
// replaceNodeExternalIPSecOutRoute replace the out IPSec route in the host
// routing table with the new route. If no route exists the route is installed
// on the host. The caller must ensure that the CIDR passed in must be non-nil.
func (n *linuxNodeHandler) replaceNodeExternalIPSecOutRoute(ip *net.IPNet) {
if ip == nil {
return
}

if ip.IP.To4() != nil {
if !n.nodeConfig.EnableIPv4 {
return
Expand All @@ -1242,19 +1238,16 @@ func (n *linuxNodeHandler) replaceNodeExternalIPSecOutRoute(ip *net.IPNet) {

_, err := route.Upsert(n.createNodeExternalIPSecOutRoute(ip, true))
if err != nil {
log.WithError(err).Error("Unable to replace the IPSec route OUT the default routing table")
log.WithError(err).WithField(logfields.CIDR, ip).Error("Unable to replace the IPSec route OUT the default routing table")
}
_, err = route.Upsert(n.createNodeExternalIPSecOutRoute(ip, false))
if err != nil {
log.WithError(err).Error("Unable to replace the IPSec route OUT the host routing table")
log.WithError(err).WithField(logfields.CIDR, ip).Error("Unable to replace the IPSec route OUT the host routing table")
}
}

// The caller must ensure that the CIDR passed in must be non-nil.
func (n *linuxNodeHandler) deleteNodeIPSecOutRoute(ip *net.IPNet) {
if ip == nil {
return
}

if ip.IP.To4() != nil {
if !n.nodeConfig.EnableIPv4 {
return
Expand All @@ -1266,15 +1259,12 @@ func (n *linuxNodeHandler) deleteNodeIPSecOutRoute(ip *net.IPNet) {
}

if err := route.Delete(n.createNodeIPSecOutRoute(ip)); err != nil {
log.WithError(err).Error("Unable to delete the IPsec route OUT from the host routing table")
log.WithError(err).WithField(logfields.CIDR, ip).Error("Unable to delete the IPsec route OUT from the host routing table")
}
}

// The caller must ensure that the CIDR passed in must be non-nil.
func (n *linuxNodeHandler) deleteNodeExternalIPSecOutRoute(ip *net.IPNet) {
if ip == nil {
return
}

if ip.IP.To4() != nil {
if !n.nodeConfig.EnableIPv4 {
return
Expand All @@ -1286,21 +1276,18 @@ func (n *linuxNodeHandler) deleteNodeExternalIPSecOutRoute(ip *net.IPNet) {
}

if err := route.Delete(n.createNodeExternalIPSecOutRoute(ip, true)); err != nil {
log.WithError(err).Error("Unable to delete the IPsec route External OUT from the ipsec routing table")
log.WithError(err).WithField(logfields.CIDR, ip).Error("Unable to delete the IPsec route External OUT from the ipsec routing table")
}

if err := route.Delete(n.createNodeExternalIPSecOutRoute(ip, false)); err != nil {
log.WithError(err).Error("Unable to delete the IPsec route External OUT from the host routing table")
log.WithError(err).WithField(logfields.CIDR, ip).Error("Unable to delete the IPsec route External OUT from the host routing table")
}
}

// replaceNodeIPSecoInRoute replace the in IPSec routes in the host routing table
// with the new route. If no route exists the route is installed on the host.
// replaceNodeIPSecoInRoute replace the in IPSec routes in the host routing
// table with the new route. If no route exists the route is installed on the
// host. The caller must ensure that the CIDR passed in must be non-nil.
func (n *linuxNodeHandler) replaceNodeIPSecInRoute(ip *net.IPNet) {
if ip == nil {
return
}

if ip.IP.To4() != nil {
if !n.nodeConfig.EnableIPv4 {
return
Expand All @@ -1313,7 +1300,7 @@ func (n *linuxNodeHandler) replaceNodeIPSecInRoute(ip *net.IPNet) {

_, err := route.Upsert(n.createNodeIPSecInRoute(ip))
if err != nil {
log.WithError(err).Error("Unable to replace the IPSec route IN the host routing table")
log.WithError(err).WithField(logfields.CIDR, ip).Error("Unable to replace the IPSec route IN the host routing table")
}
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/datapath/node.go
Expand Up @@ -127,8 +127,9 @@ type NodeHandler interface {
// NodeDelete is called after a node has been deleted
NodeDelete(node nodeTypes.Node) error

// NodeValidateImplementation is called to validate the implementation
// of the node in the datapath
// NodeValidateImplementation is called to validate the implementation of
// the node in the datapath. This function is intended to be run on an
// interval to ensure that the datapath is consistently converged.
NodeValidateImplementation(node nodeTypes.Node) error

// NodeConfigurationChanged is called when the local node configuration
Expand Down
2 changes: 2 additions & 0 deletions pkg/node/manager/manager.go
Expand Up @@ -281,6 +281,8 @@ func (m *Manager) backgroundSyncInterval() time.Duration {
return m.ClusterSizeDependantInterval(baseBackgroundSyncInterval)
}

// backgroundSync ensures that local node has a valid datapath in-place for
// each node in the cluster. See NodeValidateImplementation().
func (m *Manager) backgroundSync() {
syncTimer, syncTimerDone := inctimer.New()
defer syncTimerDone()
Expand Down