From 5bcd33c930dc95dd41ce2c8bd9c5432a956878d1 Mon Sep 17 00:00:00 2001 From: Hendrik van Wyk Date: Fri, 26 Jul 2019 10:54:15 +0200 Subject: [PATCH] Fix incorrect xfrm policy being deleted by ipsec.Destroy(). Added a check to make sure the xfrm policy has not yet been updated to a new spi. The ipsec mutex is held at this point so nothing else should be modifying this policy. --- net/ipsec/ipsec.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/net/ipsec/ipsec.go b/net/ipsec/ipsec.go index db2959b4..aa49f32e 100644 --- a/net/ipsec/ipsec.go +++ b/net/ipsec/ipsec.go @@ -223,9 +223,19 @@ func (ipsec *IPSec) Destroy(localPeer, remotePeer mesh.PeerName, connUID uint64, if outSPIInfo, ok := ipsec.spiInfo[outSPIID]; ok { ipsec.log.Infof("ipsec: destroy: out %s -> %s 0x%x", localIP, remoteIP, outSPIInfo.spi) - - if err := netlink.XfrmPolicyDel(xfrmPolicy(localIP, remoteIP, outSPIInfo.spi)); err != nil { - ipsec.log.Warnf("ipsec: xfrm policy del (%s, %s, 0x%x) failed: %s", localIP, remoteIP, outSPIInfo.spi, err) + policy, err := netlink.XfrmPolicyGet(xfrmPolicy(localIP, remoteIP, outSPIInfo.spi)) + if err != nil { + ipsec.log.Warnf("ipsec: xfrm policy get (%s, %s, 0x%x) failed: %s", localIP, remoteIP, outSPIInfo.spi, err) + } else { + if len(policy.Tmpls) == 1 { + if policy.Tmpls[0].Spi == int(outSPIInfo.spi) { + if err := netlink.XfrmPolicyDel(xfrmPolicy(localIP, remoteIP, outSPIInfo.spi)); err != nil { + ipsec.log.Warnf("ipsec: xfrm policy del (%s, %s, 0x%x) failed: %s", localIP, remoteIP, outSPIInfo.spi, err) + } + } else { + ipsec.log.Debugf("ipsec: xfrm not my policy (%s, %s, 0x%x) got 0x%x ", localIP, remoteIP, outSPIInfo.spi, policy.Tmpls[0].Spi) + } + } } outSA := &netlink.XfrmState{