Skip to content

Commit

Permalink
ipsec: Log XFRM errors during temporary state removal
Browse files Browse the repository at this point in the history
Context: During IPsec upgrades, we may have to temporarily remove some
XFRM states due to conflicts with the new states and because the Linux
API doesn't enable us to perform this atomically as we do for XFRM
policies.

This temporary removal should be very short but can still cause drops
under heavy throughput. This commit logs how many such drops happened.

Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
  • Loading branch information
pchaigno committed May 2, 2024
1 parent bba016e commit 76d6670
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion pkg/datapath/linux/ipsec/ipsec_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/cilium/hive/cell"
"github.com/cilium/hive/job"
"github.com/fsnotify/fsnotify"
"github.com/prometheus/procfs"
"github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"

Expand Down Expand Up @@ -402,6 +403,18 @@ func xfrmStateReplace(new *netlink.XfrmState, remoteRebooted bool) error {
// conflicting XFRM state. This function removes the conflicting state and
// prepares a defer callback to re-add it with proper logging.
func xfrmTemporarilyRemoveState(scopedLog *logrus.Entry, state netlink.XfrmState, dir string) (error, func()) {
stats, err := procfs.NewXfrmStat()
errorCnt := 0
if err != nil {
log.WithError(err).Error("Error while getting XFRM stats before state removal")
} else {
if dir == "IN" {
errorCnt = stats.XfrmInNoStates
} else {
errorCnt = stats.XfrmOutNoStates
}
}

start := time.Now()
if err := netlink.XfrmStateDel(&state); err != nil {
return err, nil
Expand All @@ -411,7 +424,19 @@ func xfrmTemporarilyRemoveState(scopedLog *logrus.Entry, state netlink.XfrmState
scopedLog.WithError(err).Errorf("Failed to re-add old XFRM %s state", dir)
}
elapsed := time.Since(start)
scopedLog.WithField(logfields.Duration, elapsed).Infof("Temporarily removed old XFRM %s state", dir)

stats, err := procfs.NewXfrmStat()
if err != nil {
log.WithError(err).Error("Error while getting XFRM stats after state removal")
errorCnt = 0
} else {
if dir == "IN" {
errorCnt = stats.XfrmInNoStates - errorCnt
} else {
errorCnt = stats.XfrmOutNoStates - errorCnt
}
}
scopedLog.WithField(logfields.Duration, elapsed).Infof("Temporarily removed old XFRM %s state (%d packets dropped)", dir, errorCnt)
}
}

Expand Down

0 comments on commit 76d6670

Please sign in to comment.