[ipvs] Add support for timeout configuration (Get/SetConfig)

Signed-off-by: Laurent Bernaille <laurent.bernaille@datadoghq.com>
This commit is contained in:
Laurent Bernaille 2019-03-13 16:29:49 +01:00
parent 068ca7d046
commit 7374284841
2 changed files with 72 additions and 0 deletions

View File

@ -68,6 +68,13 @@ type Destination struct {
// DstStats defines IPVS destination (real server) statistics
type DstStats SvcStats
// Config defines IPVS timeout configuration
type Config struct {
TimeoutTCP time.Duration
TimeoutTCPFin time.Duration
TimeoutUDP time.Duration
}
// Handle provides a namespace specific ipvs handle to program ipvs
// rules.
type Handle struct {
@ -188,3 +195,13 @@ func (i *Handle) GetService(s *Service) (*Service, error) {
return res[0], nil
}
// GetConfig returns the current timeout configuration
func (i *Handle) GetConfig() (*Config, error) {
return i.doGetConfigCmd()
}
// SetConfig set the current timeout configuration. 0: no change
func (i *Handle) SetConfig(c *Config) error {
return i.doSetConfigCmd(c)
}

View File

@ -12,6 +12,7 @@ import (
"sync"
"sync/atomic"
"syscall"
"time"
"unsafe"
"github.com/sirupsen/logrus"
@ -503,6 +504,60 @@ func (i *Handle) doGetDestinationsCmd(s *Service, d *Destination) ([]*Destinatio
return res, nil
}
// parseConfig given a ipvs netlink response this function will respond with a valid config entry, an error otherwise
func (i *Handle) parseConfig(msg []byte) (*Config, error) {
var c Config
//Remove General header for this message
hdr := deserializeGenlMsg(msg)
attrs, err := nl.ParseRouteAttr(msg[hdr.Len():])
if err != nil {
return nil, err
}
for _, attr := range attrs {
attrType := int(attr.Attr.Type)
switch attrType {
case ipvsCmdAttrTimeoutTCP:
c.TimeoutTCP = time.Duration(native.Uint32(attr.Value)) * time.Second
case ipvsCmdAttrTimeoutTCPFin:
c.TimeoutTCPFin = time.Duration(native.Uint32(attr.Value)) * time.Second
case ipvsCmdAttrTimeoutUDP:
c.TimeoutUDP = time.Duration(native.Uint32(attr.Value)) * time.Second
}
}
return &c, nil
}
// doGetConfigCmd a wrapper function to be used by GetConfig
func (i *Handle) doGetConfigCmd() (*Config, error) {
msg, err := i.doCmdWithoutAttr(ipvsCmdGetConfig)
if err != nil {
return nil, err
}
res, err := i.parseConfig(msg[0])
if err != nil {
return res, err
}
return res, nil
}
// doSetConfigCmd a wrapper function to be used by SetConfig
func (i *Handle) doSetConfigCmd(c *Config) error {
req := newIPVSRequest(ipvsCmdSetConfig)
req.Seq = atomic.AddUint32(&i.seq, 1)
req.AddData(nl.NewRtAttr(ipvsCmdAttrTimeoutTCP, nl.Uint32Attr(uint32(c.TimeoutTCP.Seconds()))))
req.AddData(nl.NewRtAttr(ipvsCmdAttrTimeoutTCPFin, nl.Uint32Attr(uint32(c.TimeoutTCPFin.Seconds()))))
req.AddData(nl.NewRtAttr(ipvsCmdAttrTimeoutUDP, nl.Uint32Attr(uint32(c.TimeoutUDP.Seconds()))))
_, err := execute(i.sock, req, 0)
return err
}
// IPVS related netlink message format explained
/* EACH NETLINK MSG is of the below format, this is what we will receive from execute() api.