ipvs.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // +build linux
  2. package ipvs
  3. import (
  4. "fmt"
  5. "net"
  6. "time"
  7. "github.com/vishvananda/netlink/nl"
  8. "github.com/vishvananda/netns"
  9. "golang.org/x/sys/unix"
  10. )
  11. const (
  12. netlinkRecvSocketsTimeout = 3 * time.Second
  13. netlinkSendSocketTimeout = 30 * time.Second
  14. )
  15. // Service defines an IPVS service in its entirety.
  16. type Service struct {
  17. // Virtual service address.
  18. Address net.IP
  19. Protocol uint16
  20. Port uint16
  21. FWMark uint32 // Firewall mark of the service.
  22. // Virtual service options.
  23. SchedName string
  24. Flags uint32
  25. Timeout uint32
  26. Netmask uint32
  27. AddressFamily uint16
  28. PEName string
  29. Stats SvcStats
  30. }
  31. // SvcStats defines an IPVS service statistics
  32. type SvcStats struct {
  33. Connections uint32
  34. PacketsIn uint32
  35. PacketsOut uint32
  36. BytesIn uint64
  37. BytesOut uint64
  38. CPS uint32
  39. BPSOut uint32
  40. PPSIn uint32
  41. PPSOut uint32
  42. BPSIn uint32
  43. }
  44. // Destination defines an IPVS destination (real server) in its
  45. // entirety.
  46. type Destination struct {
  47. Address net.IP
  48. Port uint16
  49. Weight int
  50. ConnectionFlags uint32
  51. AddressFamily uint16
  52. UpperThreshold uint32
  53. LowerThreshold uint32
  54. ActiveConnections int
  55. InactiveConnections int
  56. Stats DstStats
  57. }
  58. // DstStats defines IPVS destination (real server) statistics
  59. type DstStats SvcStats
  60. // Config defines IPVS timeout configuration
  61. type Config struct {
  62. TimeoutTCP time.Duration
  63. TimeoutTCPFin time.Duration
  64. TimeoutUDP time.Duration
  65. }
  66. // Handle provides a namespace specific ipvs handle to program ipvs
  67. // rules.
  68. type Handle struct {
  69. seq uint32
  70. sock *nl.NetlinkSocket
  71. }
  72. // New provides a new ipvs handle in the namespace pointed to by the
  73. // passed path. It will return a valid handle or an error in case an
  74. // error occurred while creating the handle.
  75. func New(path string) (*Handle, error) {
  76. setup()
  77. n := netns.None()
  78. if path != "" {
  79. var err error
  80. n, err = netns.GetFromPath(path)
  81. if err != nil {
  82. return nil, err
  83. }
  84. }
  85. defer n.Close()
  86. sock, err := nl.GetNetlinkSocketAt(n, netns.None(), unix.NETLINK_GENERIC)
  87. if err != nil {
  88. return nil, err
  89. }
  90. // Add operation timeout to avoid deadlocks
  91. tv := unix.NsecToTimeval(netlinkSendSocketTimeout.Nanoseconds())
  92. if err := sock.SetSendTimeout(&tv); err != nil {
  93. return nil, err
  94. }
  95. tv = unix.NsecToTimeval(netlinkRecvSocketsTimeout.Nanoseconds())
  96. if err := sock.SetReceiveTimeout(&tv); err != nil {
  97. return nil, err
  98. }
  99. return &Handle{sock: sock}, nil
  100. }
  101. // Close closes the ipvs handle. The handle is invalid after Close
  102. // returns.
  103. func (i *Handle) Close() {
  104. if i.sock != nil {
  105. i.sock.Close()
  106. }
  107. }
  108. // NewService creates a new ipvs service in the passed handle.
  109. func (i *Handle) NewService(s *Service) error {
  110. return i.doCmd(s, nil, ipvsCmdNewService)
  111. }
  112. // IsServicePresent queries for the ipvs service in the passed handle.
  113. func (i *Handle) IsServicePresent(s *Service) bool {
  114. return nil == i.doCmd(s, nil, ipvsCmdGetService)
  115. }
  116. // UpdateService updates an already existing service in the passed
  117. // handle.
  118. func (i *Handle) UpdateService(s *Service) error {
  119. return i.doCmd(s, nil, ipvsCmdSetService)
  120. }
  121. // DelService deletes an already existing service in the passed
  122. // handle.
  123. func (i *Handle) DelService(s *Service) error {
  124. return i.doCmd(s, nil, ipvsCmdDelService)
  125. }
  126. // Flush deletes all existing services in the passed
  127. // handle.
  128. func (i *Handle) Flush() error {
  129. _, err := i.doCmdWithoutAttr(ipvsCmdFlush)
  130. return err
  131. }
  132. // NewDestination creates a new real server in the passed ipvs
  133. // service which should already be existing in the passed handle.
  134. func (i *Handle) NewDestination(s *Service, d *Destination) error {
  135. return i.doCmd(s, d, ipvsCmdNewDest)
  136. }
  137. // UpdateDestination updates an already existing real server in the
  138. // passed ipvs service in the passed handle.
  139. func (i *Handle) UpdateDestination(s *Service, d *Destination) error {
  140. return i.doCmd(s, d, ipvsCmdSetDest)
  141. }
  142. // DelDestination deletes an already existing real server in the
  143. // passed ipvs service in the passed handle.
  144. func (i *Handle) DelDestination(s *Service, d *Destination) error {
  145. return i.doCmd(s, d, ipvsCmdDelDest)
  146. }
  147. // GetServices returns an array of services configured on the Node
  148. func (i *Handle) GetServices() ([]*Service, error) {
  149. return i.doGetServicesCmd(nil)
  150. }
  151. // GetDestinations returns an array of Destinations configured for this Service
  152. func (i *Handle) GetDestinations(s *Service) ([]*Destination, error) {
  153. return i.doGetDestinationsCmd(s, nil)
  154. }
  155. // GetService gets details of a specific IPVS services, useful in updating statisics etc.,
  156. func (i *Handle) GetService(s *Service) (*Service, error) {
  157. res, err := i.doGetServicesCmd(s)
  158. if err != nil {
  159. return nil, err
  160. }
  161. // We are looking for exactly one service otherwise error out
  162. if len(res) != 1 {
  163. return nil, fmt.Errorf("Expected only one service obtained=%d", len(res))
  164. }
  165. return res[0], nil
  166. }
  167. // GetConfig returns the current timeout configuration
  168. func (i *Handle) GetConfig() (*Config, error) {
  169. return i.doGetConfigCmd()
  170. }
  171. // SetConfig set the current timeout configuration. 0: no change
  172. func (i *Handle) SetConfig(c *Config) error {
  173. return i.doSetConfigCmd(c)
  174. }