Merge pull request #3763 from weaveworks/no-lock-round-send

Move send of ipsec message outside lock
This commit is contained in:
Bryan Boreham authored and GitHub committed 2020-03-05 10:21:18 +00:00
commit 709f820ab6
2 files changed
+23 -19

No files matched your search

+9 -13
View File
@@ -85,7 +85,7 @@ func New(log *logrus.Logger) (*IPSec, error) {
// InitSALocal initializes inbound ipsec from remotePeer and triggers
// the initialization on remotePeer.
func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uint64, localIP, remoteIP net.IP, udpPort int, sessionKey *[32]byte, initRemote func([]byte) error) error {
func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uint64, localIP, remoteIP net.IP, udpPort int, sessionKey *[32]byte) ([]byte, error) {
// ID of inbound SPI
spiID := getSPIId(remotePeer, localPeer, connUID)
@@ -95,17 +95,17 @@ func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uin
// Derive SA key
nonce, err := genNonce()
if err != nil {
return errors.Wrap(err, "generate nonce")
return nil, errors.Wrap(err, "generate nonce")
}
key, err := deriveKey(sessionKey[:], nonce, localPeer)
if err != nil {
return errors.Wrap(err, "derive key")
return nil, errors.Wrap(err, "derive key")
}
// Allocate SA
sa, err := netlink.XfrmStateAllocSpi(xfrmAllocSpiState(remoteIP, localIP))
if err != nil {
return errors.Wrap(err, fmt.Sprintf("ip xfrm state allocspi (in, %s, %s)", remoteIP, localIP))
return nil, errors.Wrap(err, fmt.Sprintf("ip xfrm state allocspi (in, %s, %s)", remoteIP, localIP))
}
// Use SPI generated by the kernel. The kernel ensures {dstIP, spi} to
@@ -117,28 +117,24 @@ func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uin
// Create SA
if sa, err := xfrmState(remoteIP, localIP, spi, false, key); err == nil {
if err := netlink.XfrmStateUpdate(sa); err != nil {
return errors.Wrap(err, fmt.Sprintf("xfrm state update (in, %s, %s, 0x%x)", sa.Src, sa.Dst, sa.Spi))
return nil, errors.Wrap(err, fmt.Sprintf("xfrm state update (in, %s, %s, 0x%x)", sa.Src, sa.Dst, sa.Spi))
}
} else {
return errors.Wrap(err, "new xfrm state (in)")
return nil, errors.Wrap(err, "new xfrm state (in)")
}
// Install iptables rules
if err := ipsec.installDropNonEncrypted(localIP, remoteIP, udpPort, spi); err != nil {
return errors.Wrap(err, fmt.Sprintf("install protecting rules (%s, %s, %d, 0x%x)", localIP, remoteIP, udpPort, spi))
return nil, errors.Wrap(err, fmt.Sprintf("install protecting rules (%s, %s, %d, 0x%x)", localIP, remoteIP, udpPort, spi))
}
si := spiInfo{spi: spi, isDirOut: false}
ipsec.spiInfo[spiID] = si
ipsec.spis[spi] = &si
// Trigger the initialization on the remote peer
// Generate the message to trigger initialization on the remote peer
msg := &msgInitSARemote{nonce, spi}
if err := initRemote(msg.serialize()); err != nil {
return errors.Wrap(err, "send InitSARemote")
}
return nil
return msg.serialize(), nil
}
// InitSARemote initializes outbound ipsec to remotePeer.
+14 -6
View File
@@ -482,7 +482,7 @@ func (fastdp *FastDatapath) getVxlanVportID(udpPort int) (odp.VportID, error) {
// The netdev interface is down, so most likely bringing it up
// has failed due to the UDP port being in use.
if err := fastdp.dp.DeleteVport(vxlanVportID); err != nil {
log.Warning("Unable to remove vxlan vport %d: %s", vxlanVportID, err)
log.Warningf("Unable to remove vxlan vport %d: %s", vxlanVportID, err)
}
return 0, odp.NetlinkError(syscall.EADDRINUSE)
}
@@ -654,27 +654,26 @@ func (fwd *fastDatapathForwarder) logPrefix() string {
func (fwd *fastDatapathForwarder) Confirm() {
fwd.lock.Lock()
defer fwd.lock.Unlock()
if fwd.confirmed {
log.Fatal(fwd.logPrefix(), "already confirmed")
}
var controlMsg []byte
if fwd.fastdp.ipsec != nil && fwd.sessionKey != nil {
fwd.isEncrypted = true
log.Info("Setting up IPsec between ", fwd.fastdp.localPeer, " and ", fwd.remotePeer)
err := fwd.fastdp.ipsec.InitSALocal(
var err error
controlMsg, err = fwd.fastdp.ipsec.InitSALocal(
fwd.fastdp.localPeer.Name, fwd.remotePeer.Name, fwd.connUID,
net.IP(fwd.localIP[:]), fwd.remoteAddr.IP,
fwd.remoteAddr.Port,
fwd.sessionKey,
func(msg []byte) error {
return fwd.sendControlMsg(FastDatapathCryptoInitSARemote, msg)
},
)
if err != nil {
log.Error(fwd.logPrefix(), "ipsec init SA local failed: ", err)
fwd.handleError(err)
fwd.lock.Unlock()
return
}
}
@@ -692,6 +691,15 @@ func (fwd *fastDatapathForwarder) Confirm() {
}
fwd.heartbeatTimeout = time.NewTimer(HeartbeatTimeout)
fwd.lock.Unlock() // unlock before calling send() which may block
if err := fwd.sendControlMsg(FastDatapathCryptoInitSARemote, controlMsg); err != nil {
log.Error(fwd.logPrefix(), "ipsec send InitSARemote failed: ", err)
fwd.handleError(err)
return
}
go fwd.doHeartbeats()
}