github.com/cilium/cilium@v1.16.2/tools/sysctlfix/main.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package main 5 6 import ( 7 "context" 8 "fmt" 9 "io" 10 "os" 11 "path" 12 "time" 13 14 "github.com/coreos/go-systemd/v22/dbus" 15 "github.com/spf13/pflag" 16 17 "github.com/cilium/cilium/pkg/safeio" 18 ) 19 20 // This tool attempts to write a sysctl config file to the sysctl config directory with the highest precedence so 21 // we can overwrite any other config and ensure correct sysctl options for Cilium to function. 22 23 var ( 24 flagSet = pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) 25 26 sysctlD = flagSet.String("sysctl-conf-dir", "/etc/sysctl.d/", "Path to the sysctl config directory") 27 // The 99-zzz prefix ensures our config file gets precedence over most if not all other files. 28 ciliumOverwrites = flagSet.String( 29 "sysctl-config-file", 30 "99-zzz-override_cilium.conf", 31 "Filename of the cilium sysctl overwrites config file", 32 ) 33 // Name of the systemd-sysctl unit to restart after making changes 34 sysctlUnit = flagSet.String( 35 "systemd-sysctl-unit", 36 "systemd-sysctl.service", 37 "Name of the systemd sysctl unit to reload", 38 ) 39 ) 40 41 var sysctlConfig = ` 42 # Disable rp_filter on Cilium interfaces since it may cause mangled packets to be dropped 43 -net.ipv4.conf.lxc*.rp_filter = 0 44 -net.ipv4.conf.cilium_*.rp_filter = 0 45 # The kernel uses max(conf.all, conf.{dev}) as its value, so we need to set .all. to 0 as well. 46 # Otherwise it will overrule the device specific settings. 47 net.ipv4.conf.all.rp_filter = 0 48 ` 49 50 // This program is executed by an init container so we purposely don't 51 // exit with any error codes. In case of errors, the function will print warnings, 52 // but we don't block cilium agent pod from running. 53 func main() { 54 err := flagSet.Parse(os.Args[1:]) 55 if err != nil { 56 fmt.Printf("parse flags: %s\n", err) 57 return 58 } 59 60 info, err := os.Stat(*sysctlD) 61 if err != nil { 62 fmt.Printf("can't stat sysctl.d dir '%s': %s\n", *sysctlD, err) 63 return 64 } 65 66 if !info.IsDir() { 67 fmt.Printf("'%s' is not a directory\n", *sysctlD) 68 return 69 } 70 71 overwritesPath := path.Join(*sysctlD, *ciliumOverwrites) 72 f, err := os.OpenFile(overwritesPath, os.O_RDWR|os.O_CREATE, 0644) 73 if err != nil { 74 fmt.Printf("unable to create cilium sysctl overwrites config: %s\n", err) 75 return 76 } 77 defer f.Close() 78 79 currentContents, err := safeio.ReadAllLimit(f, safeio.MB) 80 if err != nil { 81 fmt.Printf("read config: %s\n", err) 82 return 83 } 84 85 if string(currentContents) == sysctlConfig { 86 fmt.Println("sysctl config up-to-date, nothing to do") 87 return 88 } 89 90 _, err = f.Seek(0, io.SeekStart) 91 if err != nil { 92 fmt.Printf("error while seeking to start of sysctl config: %s\n", err) 93 return 94 } 95 96 // Truncate the whole file 97 err = f.Truncate(0) 98 if err != nil { 99 fmt.Printf("error while truncating sysctl config: %s\n", err) 100 return 101 } 102 103 _, err = fmt.Fprint(f, sysctlConfig) 104 if err != nil { 105 fmt.Printf("error while writing to sysctl config: %s\n", err) 106 return 107 } 108 109 fmt.Println("sysctl config created/updated") 110 111 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) 112 defer cancel() 113 114 conn, err := dbus.NewSystemdConnectionContext(ctx) 115 if err != nil { 116 fmt.Printf("error while creating SystemD D-Bus connection: %s\n", err) 117 return 118 } 119 120 _, err = conn.GetUnitPropertiesContext(ctx, *sysctlUnit) 121 if err != nil { 122 fmt.Printf("can't verify unit '%s' exists: %s\n", *sysctlUnit, err) 123 return 124 } 125 126 // https://www.freedesktop.org/wiki/Software/systemd/dbus/ 127 // "The mode needs to be one of replace, fail, isolate, ignore-dependencies, ignore-requirements. 128 // If "replace" the call will start the unit and its dependencies, possibly replacing already queued jobs that 129 // conflict with this." 130 const mode = "replace" 131 132 // Restart the systemd-sysctl unit, this will trigger SystemD to apply the new config to all existing interfaces 133 // which is required for host-interfaces and reloads on existing cilium deployments. 134 _, err = conn.RestartUnitContext(ctx, *sysctlUnit, mode, nil) 135 if err != nil { 136 fmt.Printf("error while restarting unit '%s': %s\n", *sysctlUnit, err) 137 return 138 } 139 140 fmt.Printf("systemd unit '%s' restarted\n", *sysctlUnit) 141 }