ov_network.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. package overlay
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net"
  6. "os"
  7. "path/filepath"
  8. "strconv"
  9. "strings"
  10. "sync"
  11. "github.com/Sirupsen/logrus"
  12. "github.com/docker/libnetwork/datastore"
  13. "github.com/docker/libnetwork/driverapi"
  14. "github.com/docker/libnetwork/netlabel"
  15. "github.com/docker/libnetwork/netutils"
  16. "github.com/docker/libnetwork/osl"
  17. "github.com/docker/libnetwork/resolvconf"
  18. "github.com/docker/libnetwork/types"
  19. )
  20. var (
  21. hostMode bool
  22. networkOnce sync.Once
  23. networkMu sync.Mutex
  24. vniTbl = make(map[uint32]string)
  25. )
  26. type networkTable map[string]*network
  27. type subnet struct {
  28. once *sync.Once
  29. vxlanName string
  30. brName string
  31. vni uint32
  32. initErr error
  33. subnetIP *net.IPNet
  34. gwIP *net.IPNet
  35. }
  36. type subnetJSON struct {
  37. SubnetIP string
  38. GwIP string
  39. Vni uint32
  40. }
  41. type network struct {
  42. id string
  43. dbIndex uint64
  44. dbExists bool
  45. sbox osl.Sandbox
  46. endpoints endpointTable
  47. driver *driver
  48. joinCnt int
  49. once *sync.Once
  50. initEpoch int
  51. initErr error
  52. subnets []*subnet
  53. secure bool
  54. mtu int
  55. sync.Mutex
  56. }
  57. func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
  58. return nil, types.NotImplementedErrorf("not implemented")
  59. }
  60. func (d *driver) NetworkFree(id string) error {
  61. return types.NotImplementedErrorf("not implemented")
  62. }
  63. func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
  64. if id == "" {
  65. return fmt.Errorf("invalid network id")
  66. }
  67. if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" {
  68. return types.BadRequestErrorf("ipv4 pool is empty")
  69. }
  70. // Since we perform lazy configuration make sure we try
  71. // configuring the driver when we enter CreateNetwork
  72. if err := d.configure(); err != nil {
  73. return err
  74. }
  75. n := &network{
  76. id: id,
  77. driver: d,
  78. endpoints: endpointTable{},
  79. once: &sync.Once{},
  80. subnets: []*subnet{},
  81. }
  82. vnis := make([]uint32, 0, len(ipV4Data))
  83. if gval, ok := option[netlabel.GenericData]; ok {
  84. optMap := gval.(map[string]string)
  85. if val, ok := optMap[netlabel.OverlayVxlanIDList]; ok {
  86. logrus.Debugf("overlay: Received vxlan IDs: %s", val)
  87. vniStrings := strings.Split(val, ",")
  88. for _, vniStr := range vniStrings {
  89. vni, err := strconv.Atoi(vniStr)
  90. if err != nil {
  91. return fmt.Errorf("invalid vxlan id value %q passed", vniStr)
  92. }
  93. vnis = append(vnis, uint32(vni))
  94. }
  95. }
  96. if _, ok := optMap[secureOption]; ok {
  97. n.secure = true
  98. }
  99. if val, ok := optMap[netlabel.DriverMTU]; ok {
  100. var err error
  101. if n.mtu, err = strconv.Atoi(val); err != nil {
  102. return fmt.Errorf("failed to parse %v: %v", val, err)
  103. }
  104. if n.mtu < 0 {
  105. return fmt.Errorf("invalid MTU value: %v", n.mtu)
  106. }
  107. }
  108. }
  109. // If we are getting vnis from libnetwork, either we get for
  110. // all subnets or none.
  111. if len(vnis) != 0 && len(vnis) < len(ipV4Data) {
  112. return fmt.Errorf("insufficient vnis(%d) passed to overlay", len(vnis))
  113. }
  114. for i, ipd := range ipV4Data {
  115. s := &subnet{
  116. subnetIP: ipd.Pool,
  117. gwIP: ipd.Gateway,
  118. once: &sync.Once{},
  119. }
  120. if len(vnis) != 0 {
  121. s.vni = vnis[i]
  122. }
  123. n.subnets = append(n.subnets, s)
  124. }
  125. if err := n.writeToStore(); err != nil {
  126. return fmt.Errorf("failed to update data store for network %v: %v", n.id, err)
  127. }
  128. // Make sure no rule is on the way from any stale secure network
  129. if !n.secure {
  130. for _, vni := range vnis {
  131. programMangle(vni, false)
  132. }
  133. }
  134. if nInfo != nil {
  135. if err := nInfo.TableEventRegister(ovPeerTable, driverapi.EndpointObject); err != nil {
  136. return err
  137. }
  138. }
  139. d.addNetwork(n)
  140. return nil
  141. }
  142. func (d *driver) DeleteNetwork(nid string) error {
  143. if nid == "" {
  144. return fmt.Errorf("invalid network id")
  145. }
  146. // Make sure driver resources are initialized before proceeding
  147. if err := d.configure(); err != nil {
  148. return err
  149. }
  150. n := d.network(nid)
  151. if n == nil {
  152. return fmt.Errorf("could not find network with id %s", nid)
  153. }
  154. d.deleteNetwork(nid)
  155. vnis, err := n.releaseVxlanID()
  156. if err != nil {
  157. return err
  158. }
  159. if n.secure {
  160. for _, vni := range vnis {
  161. programMangle(vni, false)
  162. }
  163. }
  164. return nil
  165. }
  166. func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
  167. return nil
  168. }
  169. func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
  170. return nil
  171. }
  172. func (n *network) incEndpointCount() {
  173. n.Lock()
  174. defer n.Unlock()
  175. n.joinCnt++
  176. }
  177. func (n *network) joinSandbox(restore bool) error {
  178. // If there is a race between two go routines here only one will win
  179. // the other will wait.
  180. n.once.Do(func() {
  181. // save the error status of initSandbox in n.initErr so that
  182. // all the racing go routines are able to know the status.
  183. n.initErr = n.initSandbox(restore)
  184. })
  185. return n.initErr
  186. }
  187. func (n *network) joinSubnetSandbox(s *subnet, restore bool) error {
  188. s.once.Do(func() {
  189. s.initErr = n.initSubnetSandbox(s, restore)
  190. })
  191. return s.initErr
  192. }
  193. func (n *network) leaveSandbox() {
  194. n.Lock()
  195. defer n.Unlock()
  196. n.joinCnt--
  197. if n.joinCnt != 0 {
  198. return
  199. }
  200. // We are about to destroy sandbox since the container is leaving the network
  201. // Reinitialize the once variable so that we will be able to trigger one time
  202. // sandbox initialization(again) when another container joins subsequently.
  203. n.once = &sync.Once{}
  204. for _, s := range n.subnets {
  205. s.once = &sync.Once{}
  206. }
  207. n.destroySandbox()
  208. }
  209. // to be called while holding network lock
  210. func (n *network) destroySandbox() {
  211. if n.sbox != nil {
  212. for _, iface := range n.sbox.Info().Interfaces() {
  213. if err := iface.Remove(); err != nil {
  214. logrus.Debugf("Remove interface %s failed: %v", iface.SrcName(), err)
  215. }
  216. }
  217. for _, s := range n.subnets {
  218. if s.vxlanName != "" {
  219. err := deleteInterface(s.vxlanName)
  220. if err != nil {
  221. logrus.Warnf("could not cleanup sandbox properly: %v", err)
  222. }
  223. }
  224. }
  225. n.sbox.Destroy()
  226. n.sbox = nil
  227. }
  228. }
  229. func networkOnceInit() {
  230. if os.Getenv("_OVERLAY_HOST_MODE") != "" {
  231. hostMode = true
  232. return
  233. }
  234. err := createVxlan("testvxlan1", 1, 0)
  235. if err != nil {
  236. logrus.Errorf("Failed to create testvxlan1 interface: %v", err)
  237. return
  238. }
  239. defer deleteInterface("testvxlan1")
  240. }
  241. func (n *network) generateVxlanName(s *subnet) string {
  242. id := n.id
  243. if len(n.id) > 12 {
  244. id = n.id[:12]
  245. }
  246. return "vx_" + id + "_0"
  247. }
  248. func (n *network) generateBridgeName(s *subnet) string {
  249. id := n.id
  250. if len(n.id) > 5 {
  251. id = n.id[:5]
  252. }
  253. return n.getBridgeNamePrefix(s) + "_" + id + "_0"
  254. }
  255. func (n *network) getBridgeNamePrefix(s *subnet) string {
  256. return "ov_" + fmt.Sprintf("%06x", n.vxlanID(s))
  257. }
  258. func isOverlap(nw *net.IPNet) bool {
  259. var nameservers []string
  260. if rc, err := resolvconf.Get(); err == nil {
  261. nameservers = resolvconf.GetNameserversAsCIDR(rc.Content)
  262. }
  263. if err := netutils.CheckNameserverOverlaps(nameservers, nw); err != nil {
  264. return true
  265. }
  266. if err := netutils.CheckRouteOverlaps(nw); err != nil {
  267. return true
  268. }
  269. return false
  270. }
  271. func (n *network) restoreSubnetSandbox(s *subnet, brName, vxlanName string) error {
  272. sbox := n.sandbox()
  273. // restore overlay osl sandbox
  274. Ifaces := make(map[string][]osl.IfaceOption)
  275. brIfaceOption := make([]osl.IfaceOption, 2)
  276. brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Address(s.gwIP))
  277. brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Bridge(true))
  278. Ifaces[fmt.Sprintf("%s+%s", brName, "br")] = brIfaceOption
  279. err := sbox.Restore(Ifaces, nil, nil, nil)
  280. if err != nil {
  281. return err
  282. }
  283. Ifaces = make(map[string][]osl.IfaceOption)
  284. vxlanIfaceOption := make([]osl.IfaceOption, 1)
  285. vxlanIfaceOption = append(vxlanIfaceOption, sbox.InterfaceOptions().Master(brName))
  286. Ifaces[fmt.Sprintf("%s+%s", vxlanName, "vxlan")] = vxlanIfaceOption
  287. err = sbox.Restore(Ifaces, nil, nil, nil)
  288. if err != nil {
  289. return err
  290. }
  291. return nil
  292. }
  293. func (n *network) addInterface(srcName, dstPrefix, name string, isBridge bool) error {
  294. return nil
  295. }
  296. func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error {
  297. if hostMode {
  298. // Try to delete stale bridge interface if it exists
  299. if err := deleteInterface(brName); err != nil {
  300. deleteInterfaceBySubnet(n.getBridgeNamePrefix(s), s)
  301. }
  302. if isOverlap(s.subnetIP) {
  303. return fmt.Errorf("overlay subnet %s has conflicts in the host while running in host mode", s.subnetIP.String())
  304. }
  305. }
  306. if !hostMode {
  307. // Try to find this subnet's vni is being used in some
  308. // other namespace by looking at vniTbl that we just
  309. // populated in the once init. If a hit is found then
  310. // it must a stale namespace from previous
  311. // life. Destroy it completely and reclaim resourced.
  312. networkMu.Lock()
  313. path, ok := vniTbl[n.vxlanID(s)]
  314. networkMu.Unlock()
  315. if ok {
  316. os.Remove(path)
  317. networkMu.Lock()
  318. delete(vniTbl, n.vxlanID(s))
  319. networkMu.Unlock()
  320. }
  321. }
  322. err := createVxlan(vxlanName, n.vxlanID(s), n.maxMTU())
  323. if err != nil {
  324. return err
  325. }
  326. return nil
  327. }
  328. func (n *network) initSubnetSandbox(s *subnet, restore bool) error {
  329. brName := n.generateBridgeName(s)
  330. vxlanName := n.generateVxlanName(s)
  331. if restore {
  332. n.restoreSubnetSandbox(s, brName, vxlanName)
  333. } else {
  334. n.setupSubnetSandbox(s, brName, vxlanName)
  335. }
  336. n.Lock()
  337. s.vxlanName = vxlanName
  338. s.brName = brName
  339. n.Unlock()
  340. return nil
  341. }
  342. func (n *network) cleanupStaleSandboxes() {
  343. filepath.Walk(filepath.Dir(osl.GenerateKey("walk")),
  344. func(path string, info os.FileInfo, err error) error {
  345. _, fname := filepath.Split(path)
  346. pList := strings.Split(fname, "-")
  347. if len(pList) <= 1 {
  348. return nil
  349. }
  350. pattern := pList[1]
  351. if strings.Contains(n.id, pattern) {
  352. // Now that we have destroyed this
  353. // sandbox, remove all references to
  354. // it in vniTbl so that we don't
  355. // inadvertently destroy the sandbox
  356. // created in this life.
  357. networkMu.Lock()
  358. for vni, tblPath := range vniTbl {
  359. if tblPath == path {
  360. delete(vniTbl, vni)
  361. }
  362. }
  363. networkMu.Unlock()
  364. }
  365. return nil
  366. })
  367. }
  368. func (n *network) initSandbox(restore bool) error {
  369. n.Lock()
  370. n.initEpoch++
  371. n.Unlock()
  372. networkOnce.Do(networkOnceInit)
  373. if !restore {
  374. // If there are any stale sandboxes related to this network
  375. // from previous daemon life clean it up here
  376. n.cleanupStaleSandboxes()
  377. }
  378. // In the restore case network sandbox already exist; but we don't know
  379. // what epoch number it was created with. It has to be retrieved by
  380. // searching the net namespaces.
  381. key := ""
  382. if restore {
  383. key = osl.GenerateKey("-" + n.id)
  384. } else {
  385. key = osl.GenerateKey(fmt.Sprintf("%d-", n.initEpoch) + n.id)
  386. }
  387. sbox, err := osl.NewSandbox(key, !hostMode, restore)
  388. if err != nil {
  389. return fmt.Errorf("could not get network sandbox (oper %t): %v", restore, err)
  390. }
  391. n.setSandbox(sbox)
  392. if !restore {
  393. n.driver.peerDbUpdateSandbox(n.id)
  394. }
  395. return nil
  396. }
  397. func (d *driver) addNetwork(n *network) {
  398. d.Lock()
  399. d.networks[n.id] = n
  400. d.Unlock()
  401. }
  402. func (d *driver) deleteNetwork(nid string) {
  403. d.Lock()
  404. delete(d.networks, nid)
  405. d.Unlock()
  406. }
  407. func (d *driver) network(nid string) *network {
  408. d.Lock()
  409. networks := d.networks
  410. d.Unlock()
  411. n, ok := networks[nid]
  412. if !ok {
  413. n = d.getNetworkFromStore(nid)
  414. if n != nil {
  415. n.driver = d
  416. n.endpoints = endpointTable{}
  417. n.once = &sync.Once{}
  418. networks[nid] = n
  419. }
  420. }
  421. return n
  422. }
  423. func (d *driver) getNetworkFromStore(nid string) *network {
  424. if d.store == nil {
  425. return nil
  426. }
  427. n := &network{id: nid}
  428. if err := d.store.GetObject(datastore.Key(n.Key()...), n); err != nil {
  429. return nil
  430. }
  431. return n
  432. }
  433. func (n *network) sandbox() osl.Sandbox {
  434. n.Lock()
  435. defer n.Unlock()
  436. return n.sbox
  437. }
  438. func (n *network) setSandbox(sbox osl.Sandbox) {
  439. n.Lock()
  440. n.sbox = sbox
  441. n.Unlock()
  442. }
  443. func (n *network) vxlanID(s *subnet) uint32 {
  444. n.Lock()
  445. defer n.Unlock()
  446. return s.vni
  447. }
  448. func (n *network) setVxlanID(s *subnet, vni uint32) {
  449. n.Lock()
  450. s.vni = vni
  451. n.Unlock()
  452. }
  453. func (n *network) Key() []string {
  454. return []string{"overlay", "network", n.id}
  455. }
  456. func (n *network) KeyPrefix() []string {
  457. return []string{"overlay", "network"}
  458. }
  459. func (n *network) Value() []byte {
  460. m := map[string]interface{}{}
  461. netJSON := []*subnetJSON{}
  462. for _, s := range n.subnets {
  463. sj := &subnetJSON{
  464. SubnetIP: s.subnetIP.String(),
  465. GwIP: s.gwIP.String(),
  466. Vni: s.vni,
  467. }
  468. netJSON = append(netJSON, sj)
  469. }
  470. b, err := json.Marshal(netJSON)
  471. if err != nil {
  472. return []byte{}
  473. }
  474. m["secure"] = n.secure
  475. m["subnets"] = netJSON
  476. m["mtu"] = n.mtu
  477. b, err = json.Marshal(m)
  478. if err != nil {
  479. return []byte{}
  480. }
  481. return b
  482. }
  483. func (n *network) Index() uint64 {
  484. return n.dbIndex
  485. }
  486. func (n *network) SetIndex(index uint64) {
  487. n.dbIndex = index
  488. n.dbExists = true
  489. }
  490. func (n *network) Exists() bool {
  491. return n.dbExists
  492. }
  493. func (n *network) Skip() bool {
  494. return false
  495. }
  496. func (n *network) SetValue(value []byte) error {
  497. var (
  498. m map[string]interface{}
  499. newNet bool
  500. isMap = true
  501. netJSON = []*subnetJSON{}
  502. )
  503. if err := json.Unmarshal(value, &m); err != nil {
  504. err := json.Unmarshal(value, &netJSON)
  505. if err != nil {
  506. return err
  507. }
  508. isMap = false
  509. }
  510. if len(n.subnets) == 0 {
  511. newNet = true
  512. }
  513. if isMap {
  514. if val, ok := m["secure"]; ok {
  515. n.secure = val.(bool)
  516. }
  517. if val, ok := m["mtu"]; ok {
  518. n.mtu = int(val.(float64))
  519. }
  520. bytes, err := json.Marshal(m["subnets"])
  521. if err != nil {
  522. return err
  523. }
  524. if err := json.Unmarshal(bytes, &netJSON); err != nil {
  525. return err
  526. }
  527. }
  528. for _, sj := range netJSON {
  529. subnetIPstr := sj.SubnetIP
  530. gwIPstr := sj.GwIP
  531. vni := sj.Vni
  532. subnetIP, _ := types.ParseCIDR(subnetIPstr)
  533. gwIP, _ := types.ParseCIDR(gwIPstr)
  534. if newNet {
  535. s := &subnet{
  536. subnetIP: subnetIP,
  537. gwIP: gwIP,
  538. vni: vni,
  539. once: &sync.Once{},
  540. }
  541. n.subnets = append(n.subnets, s)
  542. } else {
  543. sNet := n.getMatchingSubnet(subnetIP)
  544. if sNet != nil {
  545. sNet.vni = vni
  546. }
  547. }
  548. }
  549. return nil
  550. }
  551. func (n *network) DataScope() string {
  552. return datastore.GlobalScope
  553. }
  554. func (n *network) writeToStore() error {
  555. if n.driver.store == nil {
  556. return nil
  557. }
  558. return n.driver.store.PutObjectAtomic(n)
  559. }
  560. func (n *network) releaseVxlanID() ([]uint32, error) {
  561. if len(n.subnets) == 0 {
  562. return nil, nil
  563. }
  564. if n.driver.store != nil {
  565. if err := n.driver.store.DeleteObjectAtomic(n); err != nil {
  566. if err == datastore.ErrKeyModified || err == datastore.ErrKeyNotFound {
  567. // In both the above cases we can safely assume that the key has been removed by some other
  568. // instance and so simply get out of here
  569. return nil, nil
  570. }
  571. return nil, fmt.Errorf("failed to delete network to vxlan id map: %v", err)
  572. }
  573. }
  574. var vnis []uint32
  575. for _, s := range n.subnets {
  576. if n.driver.vxlanIdm != nil {
  577. vni := n.vxlanID(s)
  578. vnis = append(vnis, vni)
  579. n.driver.vxlanIdm.Release(uint64(vni))
  580. }
  581. n.setVxlanID(s, 0)
  582. }
  583. return vnis, nil
  584. }
  585. func (n *network) obtainVxlanID(s *subnet) error {
  586. //return if the subnet already has a vxlan id assigned
  587. if s.vni != 0 {
  588. return nil
  589. }
  590. if n.driver.store == nil {
  591. return fmt.Errorf("no valid vxlan id and no datastore configured, cannot obtain vxlan id")
  592. }
  593. for {
  594. if err := n.driver.store.GetObject(datastore.Key(n.Key()...), n); err != nil {
  595. return fmt.Errorf("getting network %q from datastore failed %v", n.id, err)
  596. }
  597. if s.vni == 0 {
  598. vxlanID, err := n.driver.vxlanIdm.GetID()
  599. if err != nil {
  600. return fmt.Errorf("failed to allocate vxlan id: %v", err)
  601. }
  602. n.setVxlanID(s, uint32(vxlanID))
  603. if err := n.writeToStore(); err != nil {
  604. n.driver.vxlanIdm.Release(uint64(n.vxlanID(s)))
  605. n.setVxlanID(s, 0)
  606. if err == datastore.ErrKeyModified {
  607. continue
  608. }
  609. return fmt.Errorf("network %q failed to update data store: %v", n.id, err)
  610. }
  611. return nil
  612. }
  613. return nil
  614. }
  615. }
  616. // contains return true if the passed ip belongs to one the network's
  617. // subnets
  618. func (n *network) contains(ip net.IP) bool {
  619. for _, s := range n.subnets {
  620. if s.subnetIP.Contains(ip) {
  621. return true
  622. }
  623. }
  624. return false
  625. }
  626. // getSubnetforIP returns the subnet to which the given IP belongs
  627. func (n *network) getSubnetforIP(ip *net.IPNet) *subnet {
  628. for _, s := range n.subnets {
  629. // first check if the mask lengths are the same
  630. i, _ := s.subnetIP.Mask.Size()
  631. j, _ := ip.Mask.Size()
  632. if i != j {
  633. continue
  634. }
  635. if s.subnetIP.Contains(ip.IP) {
  636. return s
  637. }
  638. }
  639. return nil
  640. }
  641. // getMatchingSubnet return the network's subnet that matches the input
  642. func (n *network) getMatchingSubnet(ip *net.IPNet) *subnet {
  643. if ip == nil {
  644. return nil
  645. }
  646. for _, s := range n.subnets {
  647. // first check if the mask lengths are the same
  648. i, _ := s.subnetIP.Mask.Size()
  649. j, _ := ip.Mask.Size()
  650. if i != j {
  651. continue
  652. }
  653. if s.subnetIP.IP.Equal(ip.IP) {
  654. return s
  655. }
  656. }
  657. return nil
  658. }