@@ -19,7 +19,12 @@ package ipvs
1919import  (
2020	"net" 
2121	"strconv" 
22+ 	"strings" 
2223	"time" 
24+ 
25+ 	"fmt" 
26+ 	"k8s.io/apimachinery/pkg/util/version" 
27+ 	"k8s.io/utils/exec" 
2328)
2429
2530// Interface is an injectable interface for running ipvs commands.  Implementations must be goroutine-safe. 
@@ -68,14 +73,21 @@ const (
6873	IPVSProxyMode  =  "ipvs" 
6974)
7075
71- // Sets of IPVS required kernel modules. 
72- var  ipvsModules  =  []string {
73- 	"ip_vs" ,
74- 	"ip_vs_rr" ,
75- 	"ip_vs_wrr" ,
76- 	"ip_vs_sh" ,
77- 	"nf_conntrack_ipv4" ,
78- }
76+ // IPVS required kernel modules. 
77+ const  (
78+ 	// ModIPVS is the kernel module "ip_vs" 
79+ 	ModIPVS  string  =  "ip_vs" 
80+ 	// ModIPVSRR is the kernel module "ip_vs_rr" 
81+ 	ModIPVSRR  string  =  "ip_vs_rr" 
82+ 	// ModIPVSWRR is the kernel module "ip_vs_wrr" 
83+ 	ModIPVSWRR  string  =  "ip_vs_wrr" 
84+ 	// ModIPVSSH is the kernel module "ip_vs_sh" 
85+ 	ModIPVSSH  string  =  "ip_vs_sh" 
86+ 	// ModNfConntrackIPV4 is the module "nf_conntrack_ipv4" 
87+ 	ModNfConntrackIPV4  string  =  "nf_conntrack_ipv4" 
88+ 	// ModNfConntrack is the kernel module "nf_conntrack" 
89+ 	ModNfConntrack  string  =  "nf_conntrack" 
90+ )
7991
8092// Equal check the equality of virtual server. 
8193// We don't use struct == since it doesn't work because of slice. 
@@ -110,3 +122,29 @@ func (rs *RealServer) Equal(other *RealServer) bool {
110122		rs .Port  ==  other .Port  && 
111123		rs .Weight  ==  other .Weight 
112124}
125+ 
126+ // GetKernelVersionAndIPVSMods returns the linux kernel version and the required ipvs modules 
127+ func  GetKernelVersionAndIPVSMods (Executor  exec.Interface ) (kernelVersion  string , ipvsModules  []string , err  error ) {
128+ 	kernelVersionFile  :=  "/proc/sys/kernel/osrelease" 
129+ 	out , err  :=  Executor .Command ("cut" , "-f1" , "-d" , " " , kernelVersionFile ).CombinedOutput ()
130+ 	if  err  !=  nil  {
131+ 		return  "" , nil , fmt .Errorf ("error getting os release kernel version: %v(%s)" , err , out )
132+ 	}
133+ 	kernelVersion  =  strings .TrimSpace (string (out ))
134+ 	// parse kernel version 
135+ 	ver1 , err  :=  version .ParseGeneric (kernelVersion )
136+ 	if  err  !=  nil  {
137+ 		return  kernelVersion , nil , fmt .Errorf ("error parsing kernel version: %v(%s)" , err , kernelVersion )
138+ 	}
139+ 	// "nf_conntrack_ipv4" has been removed since v4.19 
140+ 	// see https://github.com/torvalds/linux/commit/a0ae2562c6c4b2721d9fddba63b7286c13517d9f 
141+ 	ver2 , _  :=  version .ParseGeneric ("4.19" )
142+ 	// get required ipvs modules 
143+ 	if  ver1 .LessThan (ver2 ) {
144+ 		ipvsModules  =  append (ipvsModules , ModIPVS , ModIPVSRR , ModIPVSWRR , ModIPVSSH , ModNfConntrackIPV4 )
145+ 	} else  {
146+ 		ipvsModules  =  append (ipvsModules , ModIPVS , ModIPVSRR , ModIPVSWRR , ModIPVSSH , ModNfConntrack )
147+ 	}
148+ 
149+ 	return  kernelVersion , ipvsModules , nil 
150+ }
0 commit comments