mirror of
https://github.com/cloudnativelabs/kube-router.git
synced 2025-12-26 06:01:04 +01:00
127 lines
3.7 KiB
Go
127 lines
3.7 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
const (
|
|
// From what I can see there are no IPv6 equivalents for the below options, so we only consider IPv6 here
|
|
// Network Services Configuration Paths
|
|
IPv4IPVSConntrack = "net/ipv4/vs/conntrack"
|
|
IPv4IPVSExpireNodestConn = "net/ipv4/vs/expire_nodest_conn"
|
|
IPv4IPVSExpireQuiescent = "net/ipv4/vs/expire_quiescent_template"
|
|
IPv4IPVSConnReuseMode = "net/ipv4/vs/conn_reuse_mode"
|
|
IPv4IPVSSloppyTCP = "net/ipv4/vs/sloppy_tcp"
|
|
IPv4ConfAllArpIgnore = "net/ipv4/conf/all/arp_ignore"
|
|
IPv4ConfAllArpAnnounce = "net/ipv4/conf/all/arp_announce"
|
|
IPv6ConfAllDisableIPv6 = "net/ipv6/conf/all/disable_ipv6"
|
|
|
|
// Network Routes Configuration Paths
|
|
BridgeNFCallIPTables = "net/bridge/bridge-nf-call-iptables"
|
|
BridgeNFCallIP6Tables = "net/bridge/bridge-nf-call-ip6tables"
|
|
|
|
// Template Configuration Paths
|
|
IPv4ConfRPFilterTemplate = "net/ipv4/conf/%s/rp_filter"
|
|
)
|
|
|
|
type SysctlError struct {
|
|
additionalInfo string
|
|
err error
|
|
option string
|
|
hasValue bool
|
|
value int
|
|
fatal bool
|
|
}
|
|
|
|
// Error return the error as string
|
|
func (e *SysctlError) Error() string {
|
|
value := ""
|
|
if e.hasValue {
|
|
value = fmt.Sprintf("=%d", e.value)
|
|
}
|
|
return fmt.Sprintf("Sysctl %s%s : %s (%s)", e.option, value, e.err, e.additionalInfo)
|
|
}
|
|
|
|
// IsFatal was the error fatal and reason to exit kube-router
|
|
func (e *SysctlError) IsFatal() bool {
|
|
return e.fatal
|
|
}
|
|
|
|
// Unwrap allows us to unwrap an error showing the original error
|
|
func (e *SysctlError) Unwrap() error {
|
|
return e.err
|
|
}
|
|
|
|
type SysctlConfig struct {
|
|
name string
|
|
value int8
|
|
}
|
|
|
|
func (n *SysctlConfig) CachedVal() int8 {
|
|
return n.value
|
|
}
|
|
|
|
func (n *SysctlConfig) WriteVal(val int8) *SysctlError {
|
|
err := SetSysctl(n.name, int(val))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
n.value = val
|
|
return nil
|
|
}
|
|
|
|
func sysctlStat(path string, hasValue bool, value int) (string, *SysctlError) {
|
|
sysctlPath := fmt.Sprintf("/proc/sys/%s", path)
|
|
if _, err := os.Stat(sysctlPath); err != nil {
|
|
if os.IsNotExist(err) {
|
|
return sysctlPath, &SysctlError{
|
|
"option not found, Does your kernel version support this feature?",
|
|
err, path, hasValue, value, false}
|
|
}
|
|
return sysctlPath, &SysctlError{"path existed, but could not be stat'd", err, path, hasValue, value, true}
|
|
}
|
|
return sysctlPath, nil
|
|
}
|
|
|
|
// GetSysctlSingleTemplate gets a sysctl value by first formatting the PathTemplate parameter with the substitute string
|
|
// and then getting the sysctl value and converting it into a string
|
|
func GetSysctlSingleTemplate(pathTemplate string, substitute string) (string, *SysctlError) {
|
|
actualPath := fmt.Sprintf(pathTemplate, substitute)
|
|
return GetSysctl(actualPath)
|
|
}
|
|
|
|
// GetSysctl gets a sysctl value
|
|
func GetSysctl(path string) (string, *SysctlError) {
|
|
sysctlPath, err := sysctlStat(path, false, 0)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
buf, readErr := os.ReadFile(sysctlPath)
|
|
if readErr != nil {
|
|
return "", &SysctlError{"path could not be read", err, path, false, 0, true}
|
|
}
|
|
return string(buf), nil
|
|
}
|
|
|
|
// SetSysctlSingleTemplate sets a sysctl value by first formatting the PathTemplate parameter with the substitute string
|
|
// and then setting the sysctl to the value parameter
|
|
func SetSysctlSingleTemplate(pathTemplate string, substitute string, value int) *SysctlError {
|
|
actualPath := fmt.Sprintf(pathTemplate, substitute)
|
|
return SetSysctl(actualPath, value)
|
|
}
|
|
|
|
// SetSysctl sets a sysctl value
|
|
func SetSysctl(path string, value int) *SysctlError {
|
|
sysctlPath, err := sysctlStat(path, true, value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
writeErr := os.WriteFile(sysctlPath, []byte(strconv.Itoa(value)), 0640)
|
|
if writeErr != nil {
|
|
return &SysctlError{"path could not be set", err, path, true, value, true}
|
|
}
|
|
return nil
|
|
}
|