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

configmap & utime sync: provide via hive cell #24830

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
8 changes: 0 additions & 8 deletions daemon/cmd/datapath.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/cilium/cilium/pkg/datapath/linux/ipsec"
"github.com/cilium/cilium/pkg/datapath/linux/linux_defaults"
"github.com/cilium/cilium/pkg/datapath/linux/route"
"github.com/cilium/cilium/pkg/datapath/linux/utime"
datapath "github.com/cilium/cilium/pkg/datapath/types"
"github.com/cilium/cilium/pkg/defaults"
"github.com/cilium/cilium/pkg/endpointmanager"
Expand All @@ -29,7 +28,6 @@ import (
"github.com/cilium/cilium/pkg/ipcache"
"github.com/cilium/cilium/pkg/labels"
"github.com/cilium/cilium/pkg/logging/logfields"
"github.com/cilium/cilium/pkg/maps/configmap"
"github.com/cilium/cilium/pkg/maps/ctmap"
"github.com/cilium/cilium/pkg/maps/egressmap"
"github.com/cilium/cilium/pkg/maps/eventsmap"
Expand Down Expand Up @@ -333,12 +331,6 @@ func (d *Daemon) initMaps() error {
return nil
}

if err := configmap.InitMap(); err != nil {
return err
}
// start configmap users after configmap.InitMap() above
utime.InitUTime(d.ctx, d.controllers, time.Minute)

if _, err := lxcmap.LXCMap().OpenOrCreate(); err != nil {
return err
}
Expand Down
17 changes: 17 additions & 0 deletions pkg/bpf/bpfmap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package bpf

// BpfMap defines the base interface every BPF map needs to implement.
//
// Its main purpose is to register a BPF map via value group `bpf-maps`.
//
// Example:
//
// type MapOut struct {
// cell.Out
//
// BpfMap bpf.BpfMap `group:"bpf-maps"`
// }
type BpfMap interface{}
29 changes: 22 additions & 7 deletions pkg/datapath/cells.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ import (
"log"
"path/filepath"

"github.com/cilium/cilium/pkg/bpf"
"github.com/cilium/cilium/pkg/datapath/iptables"
"github.com/cilium/cilium/pkg/datapath/link"
linuxdatapath "github.com/cilium/cilium/pkg/datapath/linux"
"github.com/cilium/cilium/pkg/datapath/linux/utime"
"github.com/cilium/cilium/pkg/datapath/types"
"github.com/cilium/cilium/pkg/defaults"
"github.com/cilium/cilium/pkg/hive"
"github.com/cilium/cilium/pkg/hive/cell"
ipcache "github.com/cilium/cilium/pkg/ipcache/types"
"github.com/cilium/cilium/pkg/maps/authmap"
"github.com/cilium/cilium/pkg/maps"
"github.com/cilium/cilium/pkg/option"
wg "github.com/cilium/cilium/pkg/wireguard/agent"
wgTypes "github.com/cilium/cilium/pkg/wireguard/types"
Expand All @@ -27,14 +29,17 @@ var Cell = cell.Module(
"datapath",
"Datapath",

// Provides all BPF Map which are already provided by via hive cell.
maps.Cell,

// Utime synchronizes utime from userspace to datapath via configmap.Map.
utime.Cell,

cell.Provide(
newWireguardAgent,
newDatapath,
),

// Provides the auth.Map which contains the authentication state between Cilium security identities.
authmap.Cell,

cell.Provide(func(dp types.Datapath) ipcache.NodeHandler {
return dp.Node()
}),
Expand Down Expand Up @@ -68,15 +73,15 @@ func newWireguardAgent(lc hive.Lifecycle) *wg.Agent {
return wgAgent
}

func newDatapath(lc hive.Lifecycle, wgAgent *wg.Agent) types.Datapath {
func newDatapath(params datapathParams) types.Datapath {
datapathConfig := linuxdatapath.DatapathConfiguration{
HostDevice: defaults.HostDevice,
ProcFs: option.Config.ProcFs,
}

iptablesManager := &iptables.IptablesManager{}

lc.Append(hive.Hook{
params.LC.Append(hive.Hook{
OnStart: func(hive.HookContext) error {
// FIXME enableIPForwarding should not live here
if err := enableIPForwarding(); err != nil {
Expand All @@ -87,5 +92,15 @@ func newDatapath(lc hive.Lifecycle, wgAgent *wg.Agent) types.Datapath {
return nil
}})

return linuxdatapath.NewDatapath(datapathConfig, iptablesManager, wgAgent)
return linuxdatapath.NewDatapath(datapathConfig, iptablesManager, params.WgAgent)
}

type datapathParams struct {
cell.In

LC hive.Lifecycle
WgAgent *wg.Agent

// Force map initialisation before loader
BpfMaps []bpf.BpfMap `group:"bpf-maps"`
}
56 changes: 56 additions & 0 deletions pkg/datapath/linux/utime/cell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package utime

import (
"context"
"fmt"
"time"

"github.com/cilium/cilium/pkg/controller"
"github.com/cilium/cilium/pkg/hive"
"github.com/cilium/cilium/pkg/hive/cell"
"github.com/cilium/cilium/pkg/maps/configmap"
)

const (
syncControllerName = "sync-utime"
syncControllerInterval = 1 * time.Minute
)

// Cell initializes and manages the utime offset synchronization.
var Cell = cell.Module(
"utime",
"Synchronizes utime offset between userspace and datapath",

cell.Invoke(initUtimeSync),
)

func initUtimeSync(lifecycle hive.Lifecycle, configMap configmap.Map) {
controllerManager := controller.NewManager()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joamaki would it be worth to have a provider for the controller manager?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of #24558?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting - will take a look.

i think something like this could help in this case - and could be refactored in the future (once its merged)


lifecycle.Append(hive.Hook{
OnStart: func(startCtx hive.HookContext) error {
ctrl := &utimeController{configMap: configMap}

// Add controller for keeping clock in sync for NTP time jumps and any difference
// between monotonic and boottime clocks.
controllerManager.UpdateController(syncControllerName,
controller.ControllerParams{
DoFunc: func(ctx context.Context) error {
return ctrl.sync()
},
RunInterval: syncControllerInterval,
},
)
return nil
},
OnStop: func(stopCtx hive.HookContext) error {
if err := controllerManager.RemoveController(syncControllerName); err != nil {
return fmt.Errorf("failed to remove controller: %w", err)
}
return nil
},
})
}
41 changes: 7 additions & 34 deletions pkg/datapath/linux/utime/utime.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,17 @@ package utime

import (
"bufio"
"context"
"fmt"
"os"
"runtime"
"time"

"golang.org/x/sys/unix"

"github.com/cilium/cilium/pkg/controller"
"github.com/cilium/cilium/pkg/maps/configmap"
)

const (
ctrlName = "sync-utime"

btimeInfoFilepath = "/proc/stat"
nClockSamples = 10

Expand Down Expand Up @@ -63,46 +59,23 @@ func (t UTime) String() string {
}

type utimeController struct {
index configmap.Index
offset UTime
}

type controllerManager interface {
UpdateController(name string, params controller.ControllerParams)
}

func InitUTime(ctx context.Context, mgr controllerManager, interval time.Duration) {
ctrl := &utimeController{
index: configmap.UTimeOffset,
}

// Add controller for keeping clock in sync for NTP time jumps and any difference
// between monotonic and boottime clocks.
mgr.UpdateController(ctrlName,
controller.ControllerParams{
DoFunc: func(ctx context.Context) error {
return ctrl.sync()
},
RunInterval: interval,
Context: ctx,
},
)
configMap configmap.Map
offset UTime
}

func (u *utimeController) sync() error {
offset := GetCurrentUTimeOffset()
offset := getCurrentUTimeOffset()
if offset != u.offset {
err := configmap.Update(u.index, uint64(offset))
if err != nil {
return err
if err := u.configMap.Update(configmap.UTimeOffset, uint64(offset)); err != nil {
return fmt.Errorf("failed to update utime offset: %w", err)
}
u.offset = offset
}
return nil
}

// GetCurrentUTimeOffset returns the current time offset to be configured for the datapath
func GetCurrentUTimeOffset() UTime {
// getCurrentUTimeOffset returns the current time offset to be configured for the datapath
func getCurrentUTimeOffset() UTime {
// boottime is in seconds since Unix epoch, delta is clock drift in nanoseconds
boottime, err := getBoottime()
if err != nil {
Expand Down
15 changes: 13 additions & 2 deletions pkg/maps/authmap/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package authmap

import (
"github.com/cilium/cilium/pkg/bpf"
"github.com/cilium/cilium/pkg/hive"
"github.com/cilium/cilium/pkg/hive/cell"
"github.com/cilium/cilium/pkg/option"
Expand All @@ -20,7 +21,7 @@ var Cell = cell.Module(
cell.Provide(newAuthMap),
)

func newAuthMap(lifecycle hive.Lifecycle) (Map, error) {
func newAuthMap(lifecycle hive.Lifecycle) MapOut {
authMap := newMap(option.Config.AuthMapEntries)

lifecycle.Append(hive.Hook{
Expand All @@ -32,5 +33,15 @@ func newAuthMap(lifecycle hive.Lifecycle) (Map, error) {
},
})

return authMap, nil
return MapOut{
AuthMap: authMap,
BpfMap: authMap,
}
}

type MapOut struct {
cell.Out

AuthMap Map
BpfMap bpf.BpfMap `group:"bpf-maps"`
}
22 changes: 22 additions & 0 deletions pkg/maps/cells.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package maps

import (
"github.com/cilium/cilium/pkg/hive/cell"
"github.com/cilium/cilium/pkg/maps/authmap"
"github.com/cilium/cilium/pkg/maps/configmap"
)

// Cell contains all cells which are providing BPF Maps.
var Cell = cell.Module(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When should I add something here vs. to the datapath cell as done for the configmap?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nvm utime.Cell is not a map.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exactly - utime just syncs the utime and uses the configmap to write from user- to kernelspace.

the cell of the configmap itself is part of the maps cell.

"maps",
"BPF Maps",

// Provides the auth.Map which contains the authentication state between Cilium security identities.
authmap.Cell,

// ConfigMap stores runtime configuration state for the Cilium datapath.
configmap.Cell,
)
43 changes: 43 additions & 0 deletions pkg/maps/configmap/cell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package configmap

import (
"github.com/cilium/cilium/pkg/bpf"
"github.com/cilium/cilium/pkg/hive"
"github.com/cilium/cilium/pkg/hive/cell"
)

// Cell initializes and manages the config map.
var Cell = cell.Module(
"config-map",
"eBPF map config contains runtime configuration state for the Cilium datapath",

cell.Provide(newMap),
)

func newMap(lifecycle hive.Lifecycle) MapOut {
configmap := newConfigMap()

lifecycle.Append(hive.Hook{
OnStart: func(startCtx hive.HookContext) error {
return configmap.init()
},
OnStop: func(stopCtx hive.HookContext) error {
return configmap.close()
},
})

return MapOut{
ConfigMap: configmap,
BpfMap: configmap,
}
}

type MapOut struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually try to avoid writing cell.Outs with group values for the fear of typoing the group name. You can get around this with a helper, e.g. func NewMapOut[Map any](m Map) MapOut[Map], but perhaps not worth adding it just yet.

cell.Out

ConfigMap Map
BpfMap bpf.BpfMap `group:"bpf-maps"`
}