mirror of
https://github.com/cloudnativelabs/kube-router.git
synced 2025-10-10 01:11:12 +02:00
195 lines
4.2 KiB
Go
195 lines
4.2 KiB
Go
package libipvs
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"syscall"
|
|
|
|
"github.com/hkwi/nlgo"
|
|
)
|
|
|
|
type AddressFamily uint16
|
|
|
|
func (af AddressFamily) String() string {
|
|
switch af {
|
|
case syscall.AF_INET:
|
|
return "inet"
|
|
case syscall.AF_INET6:
|
|
return "inet6"
|
|
default:
|
|
return fmt.Sprintf("%d", af)
|
|
}
|
|
}
|
|
|
|
type Protocol uint16
|
|
|
|
func (p Protocol) String() string {
|
|
switch p {
|
|
case syscall.IPPROTO_TCP:
|
|
return "tcp"
|
|
case syscall.IPPROTO_UDP:
|
|
return "udp"
|
|
case syscall.IPPROTO_SCTP:
|
|
return "sctp"
|
|
default:
|
|
return fmt.Sprintf("%d", p)
|
|
}
|
|
}
|
|
|
|
type Flags struct {
|
|
Flags uint32
|
|
Mask uint32
|
|
}
|
|
|
|
// Service defines an IPVS service in its entirety.
|
|
type Service struct {
|
|
// Virtual service address.
|
|
Address net.IP
|
|
Protocol Protocol
|
|
Port uint16
|
|
FWMark uint32 // Firewall mark of the service.
|
|
|
|
// Virtual service options.
|
|
SchedName string
|
|
Flags Flags
|
|
Timeout uint32
|
|
Netmask uint32
|
|
AddressFamily AddressFamily
|
|
PEName string
|
|
Stats Stats
|
|
}
|
|
|
|
// Destination defines an IPVS destination (real server) in its
|
|
// entirety.
|
|
type Destination struct {
|
|
AddressFamily AddressFamily
|
|
Address net.IP
|
|
Port uint16
|
|
|
|
FwdMethod FwdMethod
|
|
Weight uint32
|
|
|
|
UThresh uint32
|
|
LThresh uint32
|
|
|
|
ActiveConns uint32
|
|
InactConns uint32
|
|
PersistConns uint32
|
|
Stats Stats
|
|
}
|
|
|
|
type Stats struct {
|
|
Connections uint32
|
|
PacketsIn uint32
|
|
PacketsOut uint32
|
|
BytesIn uint64
|
|
BytesOut uint64
|
|
CPS uint32
|
|
PPSIn uint32
|
|
PPSOut uint32
|
|
BPSIn uint32
|
|
BPSOut uint32
|
|
}
|
|
|
|
// Pack Service to a set of nlattrs.
|
|
// If full is given, include service settings, otherwise only the identifying fields are given.
|
|
func (self *Service) attrs(full bool) nlgo.AttrSlice {
|
|
var attrs nlgo.AttrSlice
|
|
if self.FWMark != 0 {
|
|
attrs = append(attrs,
|
|
nlattr(IPVS_SVC_ATTR_AF, nlgo.U16(self.AddressFamily)),
|
|
nlattr(IPVS_SVC_ATTR_FWMARK, nlgo.U32(self.FWMark)),
|
|
)
|
|
} else if self.Protocol != 0 && self.Address != nil && self.Port != 0 {
|
|
attrs = append(attrs,
|
|
nlattr(IPVS_SVC_ATTR_AF, nlgo.U16(self.AddressFamily)),
|
|
nlattr(IPVS_SVC_ATTR_PROTOCOL, nlgo.U16(self.Protocol)),
|
|
nlattr(IPVS_SVC_ATTR_ADDR, packAddr(self.AddressFamily, self.Address)),
|
|
nlattr(IPVS_SVC_ATTR_PORT, packPort(self.Port)),
|
|
)
|
|
} else {
|
|
panic("Incomplete service id fields")
|
|
}
|
|
|
|
if full {
|
|
attrs = append(attrs,
|
|
nlattr(IPVS_SVC_ATTR_SCHED_NAME, nlgo.NulString(self.SchedName)),
|
|
nlattr(IPVS_SVC_ATTR_FLAGS, pack(&self.Flags)),
|
|
nlattr(IPVS_SVC_ATTR_TIMEOUT, nlgo.U32(self.Timeout)),
|
|
nlattr(IPVS_SVC_ATTR_NETMASK, nlgo.U32(self.Netmask)),
|
|
)
|
|
}
|
|
|
|
return attrs
|
|
}
|
|
|
|
// Dump Dest as nl attrs, using the Af of the corresponding Service.
|
|
// If full, includes Dest setting attrs, otherwise only identifying attrs.
|
|
func (self *Destination) attrs(full bool) nlgo.AttrSlice {
|
|
var attrs nlgo.AttrSlice
|
|
|
|
attrs = append(attrs,
|
|
nlattr(IPVS_DEST_ATTR_ADDR_FAMILY, nlgo.U16(self.AddressFamily)),
|
|
nlattr(IPVS_DEST_ATTR_ADDR, packAddr(self.AddressFamily, self.Address)),
|
|
nlattr(IPVS_DEST_ATTR_PORT, packPort(self.Port)),
|
|
)
|
|
|
|
if full {
|
|
attrs = append(attrs,
|
|
nlattr(IPVS_DEST_ATTR_FWD_METHOD, nlgo.U32(self.FwdMethod)),
|
|
nlattr(IPVS_DEST_ATTR_WEIGHT, nlgo.U32(self.Weight)),
|
|
nlattr(IPVS_DEST_ATTR_U_THRESH, nlgo.U32(self.UThresh)),
|
|
nlattr(IPVS_DEST_ATTR_L_THRESH, nlgo.U32(self.LThresh)),
|
|
)
|
|
}
|
|
|
|
return attrs
|
|
}
|
|
|
|
type FwdMethod uint32
|
|
|
|
func (self FwdMethod) String() string {
|
|
switch value := (uint32(self) & IP_VS_CONN_F_FWD_MASK); value {
|
|
case IP_VS_CONN_F_MASQ:
|
|
return "masq"
|
|
case IP_VS_CONN_F_LOCALNODE:
|
|
return "localnode"
|
|
case IP_VS_CONN_F_TUNNEL:
|
|
return "tunnel"
|
|
case IP_VS_CONN_F_DROUTE:
|
|
return "droute"
|
|
case IP_VS_CONN_F_BYPASS:
|
|
return "bypass"
|
|
default:
|
|
return fmt.Sprintf("%#04x", value)
|
|
}
|
|
}
|
|
|
|
func ParseFwdMethod(value string) (FwdMethod, error) {
|
|
switch value {
|
|
case "masq":
|
|
return IP_VS_CONN_F_MASQ, nil
|
|
case "tunnel":
|
|
return IP_VS_CONN_F_TUNNEL, nil
|
|
case "droute":
|
|
return IP_VS_CONN_F_DROUTE, nil
|
|
default:
|
|
return 0, fmt.Errorf("Invalid FwdMethod: %s", value)
|
|
}
|
|
}
|
|
|
|
type Version uint32
|
|
|
|
func (version Version) String() string {
|
|
return fmt.Sprintf("%d.%d.%d",
|
|
(version>>16)&0xFF,
|
|
(version>>8)&0xFF,
|
|
(version>>0)&0xFF,
|
|
)
|
|
}
|
|
|
|
type Info struct {
|
|
Version Version
|
|
ConnTabSize uint32
|
|
}
|