xfrm_monitor_linux.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package netlink
  2. import (
  3. "fmt"
  4. "syscall"
  5. "github.com/vishvananda/netns"
  6. "github.com/vishvananda/netlink/nl"
  7. )
  8. type XfrmMsg interface {
  9. Type() nl.XfrmMsgType
  10. }
  11. type XfrmMsgExpire struct {
  12. XfrmState *XfrmState
  13. Hard bool
  14. }
  15. func (ue *XfrmMsgExpire) Type() nl.XfrmMsgType {
  16. return nl.XFRM_MSG_EXPIRE
  17. }
  18. func parseXfrmMsgExpire(b []byte) *XfrmMsgExpire {
  19. var e XfrmMsgExpire
  20. msg := nl.DeserializeXfrmUserExpire(b)
  21. e.XfrmState = xfrmStateFromXfrmUsersaInfo(&msg.XfrmUsersaInfo)
  22. e.Hard = msg.Hard == 1
  23. return &e
  24. }
  25. func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error,
  26. types ...nl.XfrmMsgType) error {
  27. groups, err := xfrmMcastGroups(types)
  28. if err != nil {
  29. return nil
  30. }
  31. s, err := nl.SubscribeAt(netns.None(), netns.None(), syscall.NETLINK_XFRM, groups...)
  32. if err != nil {
  33. return err
  34. }
  35. if done != nil {
  36. go func() {
  37. <-done
  38. s.Close()
  39. }()
  40. }
  41. go func() {
  42. defer close(ch)
  43. for {
  44. msgs, err := s.Receive()
  45. if err != nil {
  46. errorChan <- err
  47. return
  48. }
  49. for _, m := range msgs {
  50. switch m.Header.Type {
  51. case nl.XFRM_MSG_EXPIRE:
  52. ch <- parseXfrmMsgExpire(m.Data)
  53. default:
  54. errorChan <- fmt.Errorf("unsupported msg type: %x", m.Header.Type)
  55. }
  56. }
  57. }
  58. }()
  59. return nil
  60. }
  61. func xfrmMcastGroups(types []nl.XfrmMsgType) ([]uint, error) {
  62. groups := make([]uint, 0)
  63. if len(types) == 0 {
  64. return nil, fmt.Errorf("no xfrm msg type specified")
  65. }
  66. for _, t := range types {
  67. var group uint
  68. switch t {
  69. case nl.XFRM_MSG_EXPIRE:
  70. group = nl.XFRMNLGRP_EXPIRE
  71. default:
  72. return nil, fmt.Errorf("unsupported group: %x", t)
  73. }
  74. groups = append(groups, group)
  75. }
  76. return groups, nil
  77. }