Skip to content

Commit

Permalink
[BPF] make conntrack timeouts configurable
Browse files Browse the repository at this point in the history
BPFConntrackTimers overides the default values for the specified conntrack timer if
set. It is a key-value make, where each value can be either a duration or `auto` to
pick the value from a Linux conntrack timeout.

Possible values for the keys are: CreationGracePeriod, TCPPreEstablished,
TCPEstablished, TCPFinsSeen, TCPResetSeen, UDPLastSeen, GenericIPLastSeen,
ICMPLastSeen.

Unset or incorrect values are replaced by the default values with a warning log for
incorrect values.

Current auto mappings:

TCPPreEstablished: nf_conntrack_tcp_timeout_syn_sent
TCPEstablished:    nf_conntrack_tcp_timeout_established
TCPFinsSeen:       nf_conntrack_tcp_timeout_time_wait
GenericIPLastSeen: nf_conntrack_generic_timeout
ICMPLastSeen:      nf_conntrack_icmp_timeout

If there is no mapping, 'auto' is replaced by the default value.

[Default:
     CreationGracePeriod: 10s
     TCPPreEstablished:   20s
     TCPEstablished:      1h
     TCPFinsSeen:         auto (30s is default)
     TCPResetSeen:        40s
     UDPLastSeen:         60s
     GenericIPLastSeen:   10m
     ICMPLastSeen:        5s
]
  • Loading branch information
tomastigera committed Dec 18, 2024
1 parent 889f33c commit 49ac572
Show file tree
Hide file tree
Showing 19 changed files with 420 additions and 2 deletions.
40 changes: 40 additions & 0 deletions api/pkg/apis/projectcalico/v3/felixconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,40 @@ type FelixConfigurationSpec struct {
// [Default: Auto]
BPFConntrackCleanupMode *BPFConntrackMode `json:"bpfConntrackMode,omitempty" validate:"omitempty,oneof=Auto Userspace BPFProgram"`

// BPFConntrackTimers overides the default values for the specified conntrack timer if
// set. It is a key-value make, where each value can be either a duration or `auto` to
// pick the value from a Linux conntrack timeout.
//
// Possible values for the keys are: CreationGracePeriod, TCPPreEstablished,
// TCPEstablished, TCPFinsSeen, TCPResetSeen, UDPLastSeen, GenericIPLastSeen,
// ICMPLastSeen.
//
// Unset or incorrect values are replaced by the default values with a warning log for
// incorrect values.
//
// Current auto mappings:
//
// TCPPreEstablished: nf_conntrack_tcp_timeout_syn_sent
// TCPEstablished: nf_conntrack_tcp_timeout_established
// TCPFinsSeen: nf_conntrack_tcp_timeout_time_wait
// GenericIPLastSeen: nf_conntrack_generic_timeout
// ICMPLastSeen: nf_conntrack_icmp_timeout
//
// If there is no mapping, 'auto' is replaced by the default value.
//
// [Default:
// CreationGracePeriod: 10s
// TCPPreEstablished: 20s
// TCPEstablished: 1h
// TCPFinsSeen: auto (30s is default)
// TCPResetSeen: 40s
// UDPLastSeen: 60s
// GenericIPLastSeen: 10m
// ICMPLastSeen: 5s
// ]
// +optional
BPFConntrackTimeouts *map[BPFConntrackTimeoutName]BPFConntrackTimeout `json:"bpfConntrackTimeouts,omitempty" validate:"omitempty"`

// BPFLogFilters is a map of key=values where the value is
// a pcap filter expression and the key is an interface name with 'all'
// denoting all interfaces, 'weps' all workload endpoints and 'heps' all host
Expand Down Expand Up @@ -936,6 +970,12 @@ type ProtoPort struct {
Net string `json:"net,omitempty"`
}

// +kubebuilder:validation:Enum=CreationGracePeriod;TCPPreEstablished;TCPEstablished;TCPFinsSeen;TCPResetSeen;UDPLastSeen;GenericIPLastSeen
type BPFConntrackTimeoutName string

// +kubebuilder:validation:Pattern=`^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|auto)$`
type BPFConntrackTimeout string

// New FelixConfiguration creates a new (zeroed) FelixConfiguration struct with the TypeMetadata
// initialized to the current version.
func NewFelixConfiguration() *FelixConfiguration {
Expand Down
11 changes: 11 additions & 0 deletions api/pkg/apis/projectcalico/v3/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions api/pkg/openapi/generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 92 additions & 0 deletions felix/bpf/conntrack/timeouts.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
package conntrack

import (
"bufio"
"fmt"
"os"
"reflect"
"strconv"
"strings"
"time"

log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -99,3 +105,89 @@ func DefaultTimeouts() Timeouts {
ICMPLastSeen: 5 * time.Second,
}
}

var linuxSysctls = map[string]string{
"TCPPreEstablished": "nf_conntrack_tcp_timeout_syn_sent",
"TCPEstablished": "nf_conntrack_tcp_timeout_established",
"TCPFinsSeen": "nf_conntrack_tcp_timeout_time_wait",
"GenericIPLastSeen": "nf_conntrack_generic_timeout",
"ICMPLastSeen": "nf_conntrack_icmp_timeout",
}

func GetTimeouts(config map[string]string) Timeouts {
t := DefaultTimeouts()

v := reflect.ValueOf(&t)
v = v.Elem()

for key, value := range config {
field := v.FieldByName(key)
if !field.IsValid() {
log.WithField("value", key).Warn("Not a valid BPF conntrack timeout, skipping")
continue
}

d, err := time.ParseDuration(value)
if err == nil {
log.WithFields(log.Fields{"name": key, "value": d}).Info("BPF conntrack timeout set")
field.SetInt(int64(d))
continue
}

if value == "auto" {
sysctl := linuxSysctls[key]
if sysctl != "" {
seconds, err := readSecondsFromFile(sysctl)
if err == nil {
d := time.Duration(seconds) * time.Second
log.WithFields(log.Fields{"name": key, "value": d}).Infof("BPF conntrack timeout set from %s", sysctl)
field.SetInt(int64(d))
continue
}
}
}

log.WithField("value", key).Warnf("Not a valid BPF conntrack timeout value, using default %s",
time.Duration(field.Int()))
}

fields := make(log.Fields)

tt := reflect.TypeOf(t)

for i := 0; i < v.NumField(); i++ {
fields[tt.Field(i).Name] = v.Field(i).Interface()
}

log.WithFields(fields).Infof("BPF conntrack timers")

return t
}

func readSecondsFromFile(nfTimeout string) (int, error) {
filePath := "/proc/sys/net/netfilter/" + nfTimeout

file, err := os.Open(filePath)
if err != nil {
return 0, fmt.Errorf("error opening file: %w", err)
}
defer file.Close()

scanner := bufio.NewScanner(file)
if scanner.Scan() {
line := scanner.Text()
line = strings.TrimSpace(line)
seconds, err := strconv.Atoi(line)
if err != nil {
return 0, fmt.Errorf("error converting the value to an integer: %w", err)
}

return seconds, nil
}

if err := scanner.Err(); err != nil {
return 0, fmt.Errorf("error reading from file: %w", err)
}

return 0, fmt.Errorf("file is empty or cannot read a line")
}
1 change: 1 addition & 0 deletions felix/config/config_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ type Config struct {
BPFLogLevel string `config:"oneof(off,info,debug);off;non-zero"`
BPFConntrackLogLevel string `config:"oneof(off,debug);off;non-zero"`
BPFConntrackCleanupMode string `config:"oneof(Auto,Userspace,BPFProgram);Auto"`
BPFConntrackTimeouts map[string]string `config:"keyvaluelist;CreationGracePeriod=10s,TCPPreEstablished=20s,TCPEstablished=1h,TCPFinsSeen=auto,TCPResetSeen=40s,UDPLastSeen=60s,GenericIPLastSeen=10m,ICMPLastSeen=5s"`
BPFLogFilters map[string]string `config:"keyvaluelist;;"`
BPFCTLBLogFilter string `config:"oneof(all);;"`
BPFDataIfacePattern *regexp.Regexp `config:"regexp;^((en|wl|ww|sl|ib)[Popsx].*|(eth|wlan|wwan|bond).*)"`
Expand Down
2 changes: 1 addition & 1 deletion felix/dataplane/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ func StartDataplaneDriver(
BPFDisableGROForIfaces: configParams.BPFDisableGROForIfaces,
XDPEnabled: configParams.XDPEnabled,
XDPAllowGeneric: configParams.GenericXDPEnabled,
BPFConntrackTimeouts: conntrack.DefaultTimeouts(), // FIXME make timeouts configurable
BPFConntrackTimeouts: conntrack.GetTimeouts(configParams.BPFConntrackTimeouts),
BPFConntrackCleanupMode: apiv3.BPFConntrackMode(configParams.BPFConntrackCleanupMode),
RouteTableManager: routeTableIndexAllocator,
MTUIfacePattern: configParams.MTUIfacePattern,
Expand Down
26 changes: 26 additions & 0 deletions felix/docs/config-params.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions felix/docs/config-params.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const (
)

const (
numBaseFelixConfigs = 151
numBaseFelixConfigs = 152
)

var _ = Describe("Test the generic configuration update processor and the concrete implementations", func() {
Expand Down
20 changes: 20 additions & 0 deletions manifests/calico-bpf.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions manifests/calico-policy-only.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 49ac572

Please sign in to comment.