cilium.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package containers
  2. import (
  3. "path/filepath"
  4. "github.com/cilium/cilium/pkg/bpf"
  5. "github.com/cilium/cilium/pkg/defaults"
  6. "github.com/cilium/cilium/pkg/loadbalancer"
  7. "github.com/cilium/cilium/pkg/maps/ctmap"
  8. "github.com/cilium/cilium/pkg/maps/lbmap"
  9. "github.com/cilium/cilium/pkg/tuple"
  10. "github.com/cilium/cilium/pkg/u8proto"
  11. "github.com/coroot/coroot-node-agent/proc"
  12. klog "github.com/sirupsen/logrus"
  13. "inet.af/netaddr"
  14. )
  15. var (
  16. ciliumCt4 *bpf.Map
  17. ciliumCt6 *bpf.Map
  18. backends4Map *bpf.Map
  19. backends6Map *bpf.Map
  20. )
  21. func init() {
  22. var err error
  23. ciliumCt4, err = bpf.OpenMap(proc.HostPath(filepath.Join(defaults.DefaultMapRoot, defaults.DefaultMapPrefix, ctmap.MapNameTCP4Global)))
  24. if err != nil {
  25. //klog.Infoln(err)
  26. } else {
  27. klog.Infoln("found cilium ebpf-map:", ctmap.MapNameTCP4Global)
  28. }
  29. ciliumCt6, err = bpf.OpenMap(proc.HostPath(filepath.Join(defaults.DefaultMapRoot, defaults.DefaultMapPrefix, ctmap.MapNameTCP6Global)))
  30. if err != nil {
  31. //klog.Infoln(err)
  32. } else {
  33. klog.Infoln("found cilium ebpf-map:", ctmap.MapNameTCP6Global)
  34. }
  35. for _, n := range []string{lbmap.Backend4MapV2Name, lbmap.Backend4MapV3Name} {
  36. backends4Map, err = bpf.OpenMap(proc.HostPath(filepath.Join(defaults.DefaultMapRoot, defaults.DefaultMapPrefix, n)))
  37. if err != nil {
  38. //klog.Infoln(err)
  39. } else {
  40. klog.Infoln("found cilium ebpf-map:", n)
  41. break
  42. }
  43. }
  44. for _, n := range []string{lbmap.Backend6MapV2Name, lbmap.Backend6MapV3Name} {
  45. backends6Map, err = bpf.OpenMap(proc.HostPath(filepath.Join(defaults.DefaultMapRoot, defaults.DefaultMapPrefix, n)))
  46. if err != nil {
  47. //klog.Infoln(err)
  48. } else {
  49. klog.Infoln("found cilium ebpf-map:", n)
  50. break
  51. }
  52. }
  53. }
  54. func lookupCiliumConntrackTable(src, dst netaddr.IPPort) *netaddr.IPPort {
  55. if src.IP().Is4() {
  56. return lookupCilium4(src, dst)
  57. }
  58. if src.IP().Is6() {
  59. return lookupCilium6(src, dst)
  60. }
  61. return nil
  62. }
  63. func lookupCilium4(src, dst netaddr.IPPort) *netaddr.IPPort {
  64. if ciliumCt4 == nil || backends4Map == nil {
  65. return nil
  66. }
  67. key := &ctmap.CtKey4Global{
  68. TupleKey4Global: tuple.TupleKey4Global{
  69. TupleKey4: tuple.TupleKey4{
  70. SourcePort: dst.Port(),
  71. SourceAddr: src.IP().As4(),
  72. DestPort: src.Port(),
  73. DestAddr: dst.IP().As4(),
  74. NextHeader: u8proto.TCP,
  75. Flags: ctmap.TUPLE_F_SERVICE,
  76. },
  77. },
  78. }
  79. v, err := ciliumCt4.Lookup(key.ToNetwork())
  80. if err != nil || v == nil {
  81. return nil
  82. }
  83. e := v.(*ctmap.CtEntry)
  84. // https://github.com/cilium/cilium/blob/v1.13.0/bpf/lib/common.h#L819
  85. // CtEntity.RxBytes stores `backend_id` if `e.Flags & TUPLE_F_SERVICE`
  86. backendId := e.RxBytes
  87. backendKey := lbmap.NewBackend4KeyV3(loadbalancer.BackendID(backendId))
  88. b, err := backends4Map.Lookup(backendKey)
  89. if err != nil || b == nil {
  90. return nil
  91. }
  92. var backend lbmap.BackendValue
  93. switch bv := b.(type) {
  94. case *lbmap.Backend4Value:
  95. backend = bv.ToHost()
  96. case *lbmap.Backend4ValueV3:
  97. backend = bv.ToHost()
  98. default:
  99. return nil
  100. }
  101. backendIP, _ := netaddr.FromStdIP(backend.GetAddress())
  102. res := netaddr.IPPortFrom(backendIP, backend.GetPort())
  103. return &res
  104. }
  105. func lookupCilium6(src, dst netaddr.IPPort) *netaddr.IPPort {
  106. if ciliumCt6 == nil || backends6Map == nil {
  107. return nil
  108. }
  109. key := &ctmap.CtKey6Global{
  110. TupleKey6Global: tuple.TupleKey6Global{
  111. TupleKey6: tuple.TupleKey6{
  112. SourcePort: dst.Port(),
  113. SourceAddr: src.IP().As16(),
  114. DestPort: src.Port(),
  115. DestAddr: dst.IP().As16(),
  116. NextHeader: u8proto.TCP,
  117. Flags: ctmap.TUPLE_F_SERVICE,
  118. },
  119. },
  120. }
  121. v, err := ciliumCt6.Lookup(key.ToNetwork())
  122. if err != nil || v == nil {
  123. return nil
  124. }
  125. e := v.(*ctmap.CtEntry)
  126. backendId := e.RxBytes
  127. backendKey := lbmap.NewBackend6KeyV3(loadbalancer.BackendID(backendId))
  128. b, err := backends6Map.Lookup(backendKey)
  129. if err != nil || b == nil {
  130. return nil
  131. }
  132. var backend lbmap.BackendValue
  133. switch bv := b.(type) {
  134. case *lbmap.Backend6Value:
  135. backend = bv.ToHost()
  136. case *lbmap.Backend6ValueV3:
  137. backend = bv.ToHost()
  138. default:
  139. return nil
  140. }
  141. backendIP, _ := netaddr.FromStdIP(backend.GetAddress())
  142. res := netaddr.IPPortFrom(backendIP, backend.GetPort())
  143. return &res
  144. }