Skip to content

Commit 6091146

Browse files
committed
[ipvs] Add support for timeout configuration (Get/SetConfig)
Signed-off-by: Laurent Bernaille <laurent.bernaille@datadoghq.com>
1 parent 5ce033c commit 6091146

2 files changed

Lines changed: 72 additions & 0 deletions

File tree

ipvs/ipvs.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ type Destination struct {
6868
// DstStats defines IPVS destination (real server) statistics
6969
type DstStats SvcStats
7070

71+
// Config defines IPVS timeout configuration
72+
type Config struct {
73+
TimeoutTCP time.Duration
74+
TimeoutTCPFin time.Duration
75+
TimeoutUDP time.Duration
76+
}
77+
7178
// Handle provides a namespace specific ipvs handle to program ipvs
7279
// rules.
7380
type Handle struct {
@@ -188,3 +195,13 @@ func (i *Handle) GetService(s *Service) (*Service, error) {
188195

189196
return res[0], nil
190197
}
198+
199+
// GetConfig returns the current timeout configuration
200+
func (i *Handle) GetConfig() (*Config, error) {
201+
return i.doGetConfigCmd()
202+
}
203+
204+
// SetConfig set the current timeout configuration. 0: no change
205+
func (i *Handle) SetConfig(c *Config) error {
206+
return i.doSetConfigCmd(c)
207+
}

ipvs/netlink.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"sync"
1313
"sync/atomic"
1414
"syscall"
15+
"time"
1516
"unsafe"
1617

1718
"github.com/sirupsen/logrus"
@@ -503,6 +504,60 @@ func (i *Handle) doGetDestinationsCmd(s *Service, d *Destination) ([]*Destinatio
503504
return res, nil
504505
}
505506

507+
// parseConfig given a ipvs netlink response this function will respond with a valid config entry, an error otherwise
508+
func (i *Handle) parseConfig(msg []byte) (*Config, error) {
509+
var c Config
510+
511+
//Remove General header for this message
512+
hdr := deserializeGenlMsg(msg)
513+
attrs, err := nl.ParseRouteAttr(msg[hdr.Len():])
514+
if err != nil {
515+
return nil, err
516+
}
517+
518+
for _, attr := range attrs {
519+
attrType := int(attr.Attr.Type)
520+
switch attrType {
521+
case ipvsCmdAttrTimeoutTCP:
522+
c.TimeoutTCP = time.Duration(native.Uint32(attr.Value)) * time.Second
523+
case ipvsCmdAttrTimeoutTCPFin:
524+
c.TimeoutTCPFin = time.Duration(native.Uint32(attr.Value)) * time.Second
525+
case ipvsCmdAttrTimeoutUDP:
526+
c.TimeoutUDP = time.Duration(native.Uint32(attr.Value)) * time.Second
527+
}
528+
}
529+
530+
return &c, nil
531+
}
532+
533+
// doGetConfigCmd a wrapper function to be used by GetConfig
534+
func (i *Handle) doGetConfigCmd() (*Config, error) {
535+
msg, err := i.doCmdWithoutAttr(ipvsCmdGetConfig)
536+
if err != nil {
537+
return nil, err
538+
}
539+
540+
res, err := i.parseConfig(msg[0])
541+
if err != nil {
542+
return res, err
543+
}
544+
return res, nil
545+
}
546+
547+
// doSetConfigCmd a wrapper function to be used by SetConfig
548+
func (i *Handle) doSetConfigCmd(c *Config) error {
549+
req := newIPVSRequest(ipvsCmdSetConfig)
550+
req.Seq = atomic.AddUint32(&i.seq, 1)
551+
552+
req.AddData(nl.NewRtAttr(ipvsCmdAttrTimeoutTCP, nl.Uint32Attr(uint32(c.TimeoutTCP.Seconds()))))
553+
req.AddData(nl.NewRtAttr(ipvsCmdAttrTimeoutTCPFin, nl.Uint32Attr(uint32(c.TimeoutTCPFin.Seconds()))))
554+
req.AddData(nl.NewRtAttr(ipvsCmdAttrTimeoutUDP, nl.Uint32Attr(uint32(c.TimeoutUDP.Seconds()))))
555+
556+
_, err := execute(i.sock, req, 0)
557+
558+
return err
559+
}
560+
506561
// IPVS related netlink message format explained
507562

508563
/* EACH NETLINK MSG is of the below format, this is what we will receive from execute() api.

0 commit comments

Comments
 (0)