Skip to content

Commit

Permalink
Watch sysctl changes to ensure expected values
Browse files Browse the repository at this point in the history
  • Loading branch information
jschwinger233 committed Jan 13, 2024
1 parent 32ea550 commit 8db2d79
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 23 deletions.
4 changes: 3 additions & 1 deletion control/control_plane_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,9 @@ func (c *controlPlaneCore) setupSkPidMonitor() error {

func (c *controlPlaneCore) bindWan(ifname string, autoConfigKernelParameter bool) error {
if autoConfigKernelParameter {
SetAcceptLocal(ifname, "1")
if err := sysctl.Set(fmt.Sprintf("net.ipv4.conf.%v.accept_local", ifname), "1", false); err != nil {
return err
}
}
return c._bindWan(ifname)
}
Expand Down
12 changes: 6 additions & 6 deletions control/netns_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,27 +140,27 @@ func (ns *DaeNetns) setupVeth() (err error) {

func (ns *DaeNetns) setupSysctl() (err error) {
// sysctl net.ipv4.conf.dae0.rp_filter=0
if err = SetRpFilter(HostVethName, "0"); err != nil {
if err = sysctl.Set(fmt.Sprintf("net.ipv4.conf.%s.rp_filter", HostVethName), "0", true); err != nil {
return fmt.Errorf("failed to set rp_filter for dae0: %v", err)
}
// sysctl net.ipv4.conf.all.rp_filter=0
if err = SetRpFilter("all", "0"); err != nil {
if err = sysctl.Set("net.ipv4.conf.all.rp_filter", "0", true); err != nil {
return fmt.Errorf("failed to set rp_filter for all: %v", err)
}
// sysctl net.ipv4.conf.dae0.arp_filter=0
if err = SetArpFilter(HostVethName, "0"); err != nil {
if err = sysctl.Set(fmt.Sprintf("net.ipv4.conf.%s.arp_filter", HostVethName), "0", true); err != nil {
return fmt.Errorf("failed to set arp_filter for dae0: %v", err)
}
// sysctl net.ipv4.conf.all.arp_filter=0
if err = SetArpFilter("all", "0"); err != nil {
if err = sysctl.Set("net.ipv4.conf.all.arp_filter", "0", true); err != nil {
return fmt.Errorf("failed to set arp_filter for all: %v", err)
}
// sysctl net.ipv4.conf.dae0.accept_local=1
if err = SetAcceptLocal(HostVethName, "1"); err != nil {
if err = sysctl.Set(fmt.Sprintf("net.ipv4.conf.%s.accept_local", HostVethName), "1", true); err != nil {
return fmt.Errorf("failed to set accept_local for dae0: %v", err)
}
// sysctl net.ipv6.conf.dae0.disable_ipv6=0
if err = SetDisableIpv6(HostVethName, "0"); err != nil {
if err = sysctl.Set(fmt.Sprintf("net.ipv6.conf.%s.disable_ipv6", HostVethName), "0", true); err != nil {
return fmt.Errorf("failed to set disable_ipv6 for dae0: %v", err)
}
// sysctl net.ipv6.conf.dae0.forwarding=1
Expand Down
90 changes: 90 additions & 0 deletions control/sysctl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package control

import (
"os"
"strings"
"sync"

"github.com/fsnotify/fsnotify"
"github.com/sirupsen/logrus"
)

const SysctlPrefixPath = "/proc/sys/"

var sysctl *SysctlManager

type SysctlManager struct {
mux sync.Mutex
watcher *fsnotify.Watcher
expectations map[string]string
}

func init() {
var err error
if sysctl, err = NewSysctlManager(); err != nil {
logrus.Fatalf("failed to create sysctl manager: %v", err)
}
}

func NewSysctlManager() (*SysctlManager, error) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}

manager := &SysctlManager{
mux: sync.Mutex{},
watcher: watcher,
expectations: map[string]string{},
}
go manager.StartWatch()
return manager, nil
}

func (s *SysctlManager) StartWatch() {
for {
select {
case event, ok := <-s.watcher.Events:
if !ok {
return
}
if event.Has(fsnotify.Write) {
logrus.Tracef("sysctl write event: %+v", event)
s.mux.Lock()
expected, ok := s.expectations[event.Name]
s.mux.Unlock()
if ok {
raw, err := os.ReadFile(event.Name)
if err != nil {
logrus.Errorf("failed to read sysctl file %s: %v", event.Name, err)
}
value := strings.TrimSpace(string(raw))
if value != expected {
logrus.Infof("sysctl %s has unexpected value %s, expected %s", event.Name, value, expected)
if err := os.WriteFile(event.Name, []byte(expected), 0644); err != nil {
logrus.Errorf("failed to write sysctl file %s: %v", event.Name, err)
}
}
}
}
case err, ok := <-s.watcher.Errors:
if !ok {
return
}
logrus.Errorf("sysctl watcher error: %v", err)
}
}
}

func (s *SysctlManager) Set(key string, value string, watch bool) (err error) {
path := SysctlPrefixPath + strings.Replace(key, ".", "/", -1)
if watch {
s.mux.Lock()
s.expectations[path] = value
s.mux.Unlock()
if err = s.watcher.Add(path); err != nil {
return
}
}
return os.WriteFile(path, []byte(value), 0644)
}
16 changes: 0 additions & 16 deletions control/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,6 @@ func SetForwarding(ifname string, val string) {
_ = setForwarding(ifname, consts.IpVersionStr_6, val)
}

func SetAcceptLocal(ifname, val string) error {
return os.WriteFile(fmt.Sprintf("/proc/sys/net/ipv4/conf/%s/accept_local", ifname), []byte(val), 0644)
}

func SetRpFilter(ifname, val string) error {
return os.WriteFile(fmt.Sprintf("/proc/sys/net/ipv4/conf/%s/rp_filter", ifname), []byte(val), 0644)
}

func SetArpFilter(ifname, val string) error {
return os.WriteFile(fmt.Sprintf("/proc/sys/net/ipv4/conf/%s/arp_filter", ifname), []byte(val), 0644)
}

func SetDisableIpv6(ifname, val string) error {
return os.WriteFile(fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname), []byte(val), 0644)
}

func checkSendRedirects(ifname string, ipversion consts.IpVersionStr) error {
path := fmt.Sprintf("/proc/sys/net/ipv%v/conf/%v/send_redirects", ipversion, ifname)
b, err := os.ReadFile(path)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ require (
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/dgryski/go-rc2 v0.0.0-20150621095337-8a9021637152 // indirect
github.com/eknkc/basex v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
Expand Down

0 comments on commit 8db2d79

Please sign in to comment.