Skip to content

Commit

Permalink
Make reverse policy filter mapping optional
Browse files Browse the repository at this point in the history
By adding a command line argument (and the appropriate configmap option).

Signed-off-by: Anastasios Papagiannis <[email protected]>
  • Loading branch information
tpapagian committed Dec 17, 2024
1 parent 5a5c584 commit 06d4488
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 33 deletions.
20 changes: 11 additions & 9 deletions cmd/tetra/debug/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,18 +200,20 @@ func PolicyfilterState(fname string) {
fmt.Printf("%d: %s\n", polId, strings.Join(ids, ","))
}

fmt.Println("--- Reverse Map ---")
if data.Reverse != nil {
fmt.Println("--- Reverse Map ---")

if len(data.Reverse) == 0 {
fmt.Printf("(empty)\n")
}
if len(data.Reverse) == 0 {
fmt.Printf("(empty)\n")
}

for cgIDs, polIds := range data.Reverse {
ids := make([]string, 0, len(polIds))
for id := range polIds {
ids = append(ids, strconv.FormatUint(uint64(id), 10))
for cgIDs, polIds := range data.Reverse {
ids := make([]string, 0, len(polIds))
for id := range polIds {
ids = append(ids, strconv.FormatUint(uint64(id), 10))
}
fmt.Printf("%d: %s\n", cgIDs, strings.Join(ids, ","))
}
fmt.Printf("%d: %s\n", cgIDs, strings.Join(ids, ","))
}
}

Expand Down
1 change: 1 addition & 0 deletions docs/content/en/docs/reference/helm-chart.md

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

3 changes: 3 additions & 0 deletions docs/data/tetragon_flags.yaml

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

1 change: 1 addition & 0 deletions install/kubernetes/tetragon/README.md

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

3 changes: 3 additions & 0 deletions install/kubernetes/tetragon/templates/tetragon_configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ data:
{{- if .Values.tetragon.enablePolicyFilter }}
enable-policy-filter: "true"
{{- end }}
{{- if .Values.tetragon.enablePolicyFilterReverseMap }}
enable-policy-filter-reverse-map: "true"
{{- end }}
{{- if .Values.tetragon.enablePolicyFilterDebug }}
enable-policy-filter-debug: "true"
{{- end }}
Expand Down
2 changes: 2 additions & 0 deletions install/kubernetes/tetragon/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ tetragon:
port: 6060
# -- Enable policy filter. This is required for K8s namespace and pod-label filtering.
enablePolicyFilter: True
# -- Enable policy filter reverse map.
enablePolicyFilterReverseMap: false
# -- Enable policy filter debug messages.
enablePolicyFilterDebug: false
# -- Enable latency monitoring in message handling
Expand Down
5 changes: 3 additions & 2 deletions pkg/option/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ type config struct {

ReleasePinned bool

EnablePolicyFilter bool
EnablePolicyFilterDebug bool
EnablePolicyFilter bool
EnablePolicyFilterReverseMap bool
EnablePolicyFilterDebug bool

EnablePidSetFilter bool

Expand Down
7 changes: 5 additions & 2 deletions pkg/option/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ const (

KeyReleasePinnedBPF = "release-pinned-bpf"

KeyEnablePolicyFilter = "enable-policy-filter"
KeyEnablePolicyFilterDebug = "enable-policy-filter-debug"
KeyEnablePolicyFilter = "enable-policy-filter"
KeyEnablePolicyFilterReverseMap = "enable-policy-filter-reverse-map"
KeyEnablePolicyFilterDebug = "enable-policy-filter-debug"

KeyEnablePidSetFilter = "enable-pid-set-filter"

Expand Down Expand Up @@ -202,6 +203,7 @@ func ReadAndSetFlags() error {

Config.ReleasePinned = viper.GetBool(KeyReleasePinnedBPF)
Config.EnablePolicyFilter = viper.GetBool(KeyEnablePolicyFilter)
Config.EnablePolicyFilterReverseMap = viper.GetBool(KeyEnablePolicyFilterReverseMap)
Config.EnablePolicyFilterDebug = viper.GetBool(KeyEnablePolicyFilterDebug)
Config.EnableMsgHandlingLatency = viper.GetBool(KeyEnableMsgHandlingLatency)

Expand Down Expand Up @@ -378,6 +380,7 @@ func AddFlags(flags *pflag.FlagSet) {
// Provide option to enable policy filtering. Because the code is new,
// this is set to false by default.
flags.Bool(KeyEnablePolicyFilter, false, "Enable policy filter code")
flags.Bool(KeyEnablePolicyFilterReverseMap, false, "Enable reverse mappings for policy filter maps")
flags.Bool(KeyEnablePolicyFilterDebug, false, "Enable policy filter debug messages")

// Provide option to enable the pidSet export filters.
Expand Down
2 changes: 1 addition & 1 deletion pkg/policyfilter/k8s_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ func TestK8s(t *testing.T) {

// testState implements cgFinder
ts := newTestState(client)
st, err := newState(log, ts)
st, err := newState(log, ts, true)
if err != nil {
t.Skipf("failed to initialize policy filter state: %s", err)
}
Expand Down
61 changes: 48 additions & 13 deletions pkg/policyfilter/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func openMap(spec *ebpf.CollectionSpec, mapName string, innerMaxEntries uint32)
}

// newMap returns a new policy filter map.
func newPfMap() (PfMap, error) {
func newPfMap(enableReverseMap bool) (PfMap, error) {
// use the generic kprobe program, to find the policy filter map spec
objName, _ := kernels.GenericKprobeObjs()
objPath := path.Join(option.Config.HubbleLib, objName)
Expand All @@ -72,13 +72,22 @@ func newPfMap() (PfMap, error) {
if ret.dir, err = openMap(spec, MapName, polMapSize); err != nil {
return PfMap{}, fmt.Errorf("opening map %s failed: %w", MapName, err)
}
if ret.rev, err = openMap(spec, RevMapName, polMaxPolicies); err != nil {
return PfMap{}, fmt.Errorf("opening reverse map %s failed: %w", MapName, err)

if enableReverseMap {
if ret.rev, err = openMap(spec, RevMapName, polMaxPolicies); err != nil {
return PfMap{}, fmt.Errorf("opening reverse map %s failed: %w", MapName, err)
}
}

return ret, nil
}

func releaseMap(m *ebpf.Map) error {
// this may happen in the case where the reverse map is not enabled
if m == nil {
return nil
}

if err := m.Close(); err != nil {
return err
}
Expand Down Expand Up @@ -114,6 +123,11 @@ func (m polMap) addCgroupIDsReverse(polID PolicyID, cgIDs []CgroupID) error {
}

func addReverseMapping(m *ebpf.Map, polID PolicyID, cgID CgroupID) error {
// reverse map does not exist, so nothing to do here
if m == nil {
return nil
}

var id uint32
err := m.Lookup(cgID, &id)
if err == nil { // inner map exists
Expand Down Expand Up @@ -221,6 +235,11 @@ func getMapSize(m *ebpf.Map) (uint32, error) {
}

func (m PfMap) deletePolicyIdInReverse(polID PolicyID) error {
// reverse map does not exist, so nothing to do here
if m.rev == nil {
return nil
}

var key CgroupID
var id uint32

Expand Down Expand Up @@ -318,9 +337,12 @@ func (m PfMap) readAll() (PfMapDump, error) {
return PfMapDump{}, fmt.Errorf("error reading direct map: %w", err)
}

r, err := readAll[CgroupID, PolicyID](m.rev)
if err != nil {
return PfMapDump{}, fmt.Errorf("error reading reverse map: %w", err)
var r map[CgroupID]map[PolicyID]struct{}
if m.rev != nil {
r, err = readAll[CgroupID, PolicyID](m.rev)
if err != nil {
return PfMapDump{}, fmt.Errorf("error reading reverse map: %w", err)
}
}

return PfMapDump{Direct: d, Reverse: r}, nil
Expand Down Expand Up @@ -365,6 +387,11 @@ func (m polMap) addCgroupIDs(cgIDs []CgroupID) error {
// delCgroupIDs delete cgroups ids from the policy map
// todo: use batch operations when supported
func (m polMap) delCgroupIDs(polID PolicyID, cgIDs []CgroupID) error {
// reverse map does not exist, so nothing to do here
if m.Reverse == nil {
return nil
}

rmRevCgIDs := []CgroupID{}
for i, cgID := range cgIDs {
if err := m.Inner.Delete(&cgID); err != nil {
Expand Down Expand Up @@ -428,21 +455,29 @@ func OpenMap(fname string) (PfMap, error) {

dir := filepath.Dir(fname)
reverseMapPath := filepath.Join(dir, RevMapName)
r, err := ebpf.LoadPinnedMap(reverseMapPath, &ebpf.LoadPinOptions{
ReadOnly: true,
})

if err != nil {
d.Close()
return PfMap{}, err
// check if the reverse map exists
// the reverse map may not exist in the case where
// enable-policy-filter-reverse-map is false
var r *ebpf.Map
if _, err := os.Stat(reverseMapPath); err == nil {
r, err = ebpf.LoadPinnedMap(reverseMapPath, &ebpf.LoadPinOptions{
ReadOnly: true,
})
if err != nil {
d.Close()
return PfMap{}, err
}
}

return PfMap{dir: d, rev: r}, err
}

func (m PfMap) Close() {
m.dir.Close()
m.rev.Close()
if m.rev != nil {
m.rev.Close()
}
}

func (m PfMap) Dump() (PfMapDump, error) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/policyfilter/map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func TestPfMapOps(t *testing.T) {
if !bpffsReady {
t.Skip("failed to initialize bpffs")
}
pfm, err := newPfMap()
pfm, err := newPfMap(true)
require.NoError(t, err)
defer pfm.release()

Expand Down
4 changes: 2 additions & 2 deletions pkg/policyfilter/policyfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func GetState() (State, error) {
setGlobalPf.Do(func() {
if option.Config.EnablePolicyFilter {
logger.GetLogger().Info("Enabling policy filtering")
glblState, glblError = New()
glblState, glblError = New(option.Config.EnablePolicyFilterReverseMap)
} else {
glblState = &disabled{}
glblError = nil
Expand All @@ -45,7 +45,7 @@ func resetStateOnlyForTesting() {
}
if option.Config.EnablePolicyFilter {
logger.GetLogger().Info("Enabling policy filtering")
glblState, glblError = New()
glblState, glblError = New(true)
} else {
glblState = &disabled{}
glblError = nil
Expand Down
6 changes: 4 additions & 2 deletions pkg/policyfilter/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,17 +269,19 @@ type state struct {
// allocated resources (namely the bpf map).
//
//revive:disable:unexported-return
func New() (*state, error) {
func New(enableReverseMap bool) (*state, error) {
log := logger.GetLogger().WithField("subsystem", "policy-filter")
return newState(
log,
&cgfsFinder{fsscan.New(), log},
enableReverseMap,
)
}

func newState(
log logrus.FieldLogger,
cgidFinder cgidFinder,
enableReverseMap bool,
) (*state, error) {
var err error
ret := &state{
Expand All @@ -288,7 +290,7 @@ func newState(
DebugLogger: logger.NewDebugLogger(log, option.Config.EnablePolicyFilterDebug),
}

ret.pfMap, err = newPfMap()
ret.pfMap, err = newPfMap(enableReverseMap)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/policyfilter/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func TestState(t *testing.T) {
s, err := New()
s, err := New(true)
if err != nil {
t.Skipf("failed to inialize policy filter state: %s", err)
}
Expand Down

0 comments on commit 06d4488

Please sign in to comment.