peerdb.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. package overlay
  2. import (
  3. "fmt"
  4. "net"
  5. "sync"
  6. "github.com/Sirupsen/logrus"
  7. )
  8. const ovPeerTable = "overlay_peer_table"
  9. type peerKey struct {
  10. peerIP net.IP
  11. peerMac net.HardwareAddr
  12. }
  13. type peerEntry struct {
  14. eid string
  15. vtep net.IP
  16. peerIPMask net.IPMask
  17. inSandbox bool
  18. isLocal bool
  19. }
  20. type peerMap struct {
  21. mp map[string]peerEntry
  22. sync.Mutex
  23. }
  24. type peerNetworkMap struct {
  25. mp map[string]*peerMap
  26. sync.Mutex
  27. }
  28. func (pKey peerKey) String() string {
  29. return fmt.Sprintf("%s %s", pKey.peerIP, pKey.peerMac)
  30. }
  31. func (pKey *peerKey) Scan(state fmt.ScanState, verb rune) error {
  32. ipB, err := state.Token(true, nil)
  33. if err != nil {
  34. return err
  35. }
  36. pKey.peerIP = net.ParseIP(string(ipB))
  37. macB, err := state.Token(true, nil)
  38. if err != nil {
  39. return err
  40. }
  41. pKey.peerMac, err = net.ParseMAC(string(macB))
  42. if err != nil {
  43. return err
  44. }
  45. return nil
  46. }
  47. var peerDbWg sync.WaitGroup
  48. func (d *driver) peerDbWalk(f func(string, *peerKey, *peerEntry) bool) error {
  49. d.peerDb.Lock()
  50. nids := []string{}
  51. for nid := range d.peerDb.mp {
  52. nids = append(nids, nid)
  53. }
  54. d.peerDb.Unlock()
  55. for _, nid := range nids {
  56. d.peerDbNetworkWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool {
  57. return f(nid, pKey, pEntry)
  58. })
  59. }
  60. return nil
  61. }
  62. func (d *driver) peerDbNetworkWalk(nid string, f func(*peerKey, *peerEntry) bool) error {
  63. d.peerDb.Lock()
  64. pMap, ok := d.peerDb.mp[nid]
  65. if !ok {
  66. d.peerDb.Unlock()
  67. return nil
  68. }
  69. d.peerDb.Unlock()
  70. pMap.Lock()
  71. for pKeyStr, pEntry := range pMap.mp {
  72. var pKey peerKey
  73. if _, err := fmt.Sscan(pKeyStr, &pKey); err != nil {
  74. logrus.Warnf("Peer key scan on network %s failed: %v", nid, err)
  75. }
  76. if f(&pKey, &pEntry) {
  77. pMap.Unlock()
  78. return nil
  79. }
  80. }
  81. pMap.Unlock()
  82. return nil
  83. }
  84. func (d *driver) peerDbSearch(nid string, peerIP net.IP) (net.HardwareAddr, net.IPMask, net.IP, error) {
  85. var (
  86. peerMac net.HardwareAddr
  87. vtep net.IP
  88. peerIPMask net.IPMask
  89. found bool
  90. )
  91. err := d.peerDbNetworkWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool {
  92. if pKey.peerIP.Equal(peerIP) {
  93. peerMac = pKey.peerMac
  94. peerIPMask = pEntry.peerIPMask
  95. vtep = pEntry.vtep
  96. found = true
  97. return found
  98. }
  99. return found
  100. })
  101. if err != nil {
  102. return nil, nil, nil, fmt.Errorf("peerdb search for peer ip %q failed: %v", peerIP, err)
  103. }
  104. if !found {
  105. return nil, nil, nil, fmt.Errorf("peer ip %q not found in peerdb", peerIP)
  106. }
  107. return peerMac, peerIPMask, vtep, nil
  108. }
  109. func (d *driver) peerDbAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
  110. peerMac net.HardwareAddr, vtep net.IP, isLocal bool) {
  111. peerDbWg.Wait()
  112. d.peerDb.Lock()
  113. pMap, ok := d.peerDb.mp[nid]
  114. if !ok {
  115. d.peerDb.mp[nid] = &peerMap{
  116. mp: make(map[string]peerEntry),
  117. }
  118. pMap = d.peerDb.mp[nid]
  119. }
  120. d.peerDb.Unlock()
  121. pKey := peerKey{
  122. peerIP: peerIP,
  123. peerMac: peerMac,
  124. }
  125. pEntry := peerEntry{
  126. eid: eid,
  127. vtep: vtep,
  128. peerIPMask: peerIPMask,
  129. isLocal: isLocal,
  130. }
  131. pMap.Lock()
  132. pMap.mp[pKey.String()] = pEntry
  133. pMap.Unlock()
  134. }
  135. func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
  136. peerMac net.HardwareAddr, vtep net.IP) {
  137. peerDbWg.Wait()
  138. d.peerDb.Lock()
  139. pMap, ok := d.peerDb.mp[nid]
  140. if !ok {
  141. d.peerDb.Unlock()
  142. return
  143. }
  144. d.peerDb.Unlock()
  145. pKey := peerKey{
  146. peerIP: peerIP,
  147. peerMac: peerMac,
  148. }
  149. pMap.Lock()
  150. delete(pMap.mp, pKey.String())
  151. pMap.Unlock()
  152. }
  153. func (d *driver) peerDbUpdateSandbox(nid string) {
  154. d.peerDb.Lock()
  155. pMap, ok := d.peerDb.mp[nid]
  156. if !ok {
  157. d.peerDb.Unlock()
  158. return
  159. }
  160. d.peerDb.Unlock()
  161. peerDbWg.Add(1)
  162. var peerOps []func()
  163. pMap.Lock()
  164. for pKeyStr, pEntry := range pMap.mp {
  165. var pKey peerKey
  166. if _, err := fmt.Sscan(pKeyStr, &pKey); err != nil {
  167. fmt.Printf("peer key scan failed: %v", err)
  168. }
  169. if pEntry.isLocal {
  170. continue
  171. }
  172. // Go captures variables by reference. The pEntry could be
  173. // pointing to the same memory location for every iteration. Make
  174. // a copy of pEntry before capturing it in the following closure.
  175. entry := pEntry
  176. op := func() {
  177. if err := d.peerAdd(nid, entry.eid, pKey.peerIP, entry.peerIPMask,
  178. pKey.peerMac, entry.vtep,
  179. false); err != nil {
  180. fmt.Printf("peerdbupdate in sandbox failed for ip %s and mac %s: %v",
  181. pKey.peerIP, pKey.peerMac, err)
  182. }
  183. }
  184. peerOps = append(peerOps, op)
  185. }
  186. pMap.Unlock()
  187. for _, op := range peerOps {
  188. op()
  189. }
  190. peerDbWg.Done()
  191. }
  192. func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
  193. peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {
  194. if err := validateID(nid, eid); err != nil {
  195. return err
  196. }
  197. if updateDb {
  198. d.peerDbAdd(nid, eid, peerIP, peerIPMask, peerMac, vtep, false)
  199. }
  200. n := d.network(nid)
  201. if n == nil {
  202. return nil
  203. }
  204. sbox := n.sandbox()
  205. if sbox == nil {
  206. return nil
  207. }
  208. IP := &net.IPNet{
  209. IP: peerIP,
  210. Mask: peerIPMask,
  211. }
  212. s := n.getSubnetforIP(IP)
  213. if s == nil {
  214. return fmt.Errorf("couldn't find the subnet %q in network %q", IP.String(), n.id)
  215. }
  216. if err := n.obtainVxlanID(s); err != nil {
  217. return fmt.Errorf("couldn't get vxlan id for %q: %v", s.subnetIP.String(), err)
  218. }
  219. if err := n.joinSubnetSandbox(s, false); err != nil {
  220. return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), err)
  221. }
  222. if err := d.checkEncryption(nid, vtep, n.vxlanID(s), false, true); err != nil {
  223. logrus.Warn(err)
  224. }
  225. // Add neighbor entry for the peer IP
  226. if err := sbox.AddNeighbor(peerIP, peerMac, false, sbox.NeighborOptions().LinkName(s.vxlanName)); err != nil {
  227. return fmt.Errorf("could not add neigbor entry into the sandbox: %v", err)
  228. }
  229. // XXX Add fdb entry to the bridge for the peer mac
  230. return nil
  231. }
  232. func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
  233. peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {
  234. if err := validateID(nid, eid); err != nil {
  235. return err
  236. }
  237. if updateDb {
  238. d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep)
  239. }
  240. n := d.network(nid)
  241. if n == nil {
  242. return nil
  243. }
  244. sbox := n.sandbox()
  245. if sbox == nil {
  246. return nil
  247. }
  248. // Delete fdb entry to the bridge for the peer mac
  249. if err := sbox.DeleteNeighbor(vtep, peerMac, true); err != nil {
  250. return fmt.Errorf("could not delete fdb entry into the sandbox: %v", err)
  251. }
  252. // Delete neighbor entry for the peer IP
  253. if err := sbox.DeleteNeighbor(peerIP, peerMac, true); err != nil {
  254. return fmt.Errorf("could not delete neigbor entry into the sandbox: %v", err)
  255. }
  256. if err := d.checkEncryption(nid, vtep, 0, false, false); err != nil {
  257. logrus.Warn(err)
  258. }
  259. return nil
  260. }
  261. func (d *driver) pushLocalDb() {
  262. d.peerDbWalk(func(nid string, pKey *peerKey, pEntry *peerEntry) bool {
  263. if pEntry.isLocal {
  264. d.pushLocalEndpointEvent("join", nid, pEntry.eid)
  265. }
  266. return false
  267. })
  268. }