ipvs.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // +build linux
  2. package ipvs
  3. import (
  4. "net"
  5. "syscall"
  6. "github.com/vishvananda/netlink/nl"
  7. "github.com/vishvananda/netns"
  8. )
  9. // Service defines an IPVS service in its entirety.
  10. type Service struct {
  11. // Virtual service address.
  12. Address net.IP
  13. Protocol uint16
  14. Port uint16
  15. FWMark uint32 // Firewall mark of the service.
  16. // Virtual service options.
  17. SchedName string
  18. Flags uint32
  19. Timeout uint32
  20. Netmask uint32
  21. AddressFamily uint16
  22. PEName string
  23. }
  24. // Destination defines an IPVS destination (real server) in its
  25. // entirety.
  26. type Destination struct {
  27. Address net.IP
  28. Port uint16
  29. Weight int
  30. ConnectionFlags uint32
  31. AddressFamily uint16
  32. UpperThreshold uint32
  33. LowerThreshold uint32
  34. }
  35. // Handle provides a namespace specific ipvs handle to program ipvs
  36. // rules.
  37. type Handle struct {
  38. seq uint32
  39. sock *nl.NetlinkSocket
  40. }
  41. // New provides a new ipvs handle in the namespace pointed to by the
  42. // passed path. It will return a valid handle or an error in case an
  43. // error occurred while creating the handle.
  44. func New(path string) (*Handle, error) {
  45. setup()
  46. n := netns.None()
  47. if path != "" {
  48. var err error
  49. n, err = netns.GetFromPath(path)
  50. if err != nil {
  51. return nil, err
  52. }
  53. }
  54. defer n.Close()
  55. sock, err := nl.GetNetlinkSocketAt(n, netns.None(), syscall.NETLINK_GENERIC)
  56. if err != nil {
  57. return nil, err
  58. }
  59. return &Handle{sock: sock}, nil
  60. }
  61. // Close closes the ipvs handle. The handle is invalid after Close
  62. // returns.
  63. func (i *Handle) Close() {
  64. if i.sock != nil {
  65. i.sock.Close()
  66. }
  67. }
  68. // NewService creates a new ipvs service in the passed handle.
  69. func (i *Handle) NewService(s *Service) error {
  70. return i.doCmd(s, nil, ipvsCmdNewService)
  71. }
  72. // IsServicePresent queries for the ipvs service in the passed handle.
  73. func (i *Handle) IsServicePresent(s *Service) bool {
  74. return nil == i.doCmd(s, nil, ipvsCmdGetService)
  75. }
  76. // UpdateService updates an already existing service in the passed
  77. // handle.
  78. func (i *Handle) UpdateService(s *Service) error {
  79. return i.doCmd(s, nil, ipvsCmdSetService)
  80. }
  81. // DelService deletes an already existing service in the passed
  82. // handle.
  83. func (i *Handle) DelService(s *Service) error {
  84. return i.doCmd(s, nil, ipvsCmdDelService)
  85. }
  86. // NewDestination creates a new real server in the passed ipvs
  87. // service which should already be existing in the passed handle.
  88. func (i *Handle) NewDestination(s *Service, d *Destination) error {
  89. return i.doCmd(s, d, ipvsCmdNewDest)
  90. }
  91. // UpdateDestination updates an already existing real server in the
  92. // passed ipvs service in the passed handle.
  93. func (i *Handle) UpdateDestination(s *Service, d *Destination) error {
  94. return i.doCmd(s, d, ipvsCmdSetDest)
  95. }
  96. // DelDestination deletes an already existing real server in the
  97. // passed ipvs service in the passed handle.
  98. func (i *Handle) DelDestination(s *Service, d *Destination) error {
  99. return i.doCmd(s, d, ipvsCmdDelDest)
  100. }