github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/libnetwork/drivers/overlay/ov_network.go (about) 1 //go:build linux 2 // +build linux 3 4 package overlay 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "net" 10 "os" 11 "os/exec" 12 "path/filepath" 13 "runtime" 14 "strconv" 15 "strings" 16 "sync" 17 18 "github.com/docker/docker/libnetwork/datastore" 19 "github.com/docker/docker/libnetwork/driverapi" 20 "github.com/docker/docker/libnetwork/netlabel" 21 "github.com/docker/docker/libnetwork/netutils" 22 "github.com/docker/docker/libnetwork/ns" 23 "github.com/docker/docker/libnetwork/osl" 24 "github.com/docker/docker/libnetwork/resolvconf" 25 "github.com/docker/docker/libnetwork/types" 26 "github.com/docker/docker/pkg/reexec" 27 "github.com/sirupsen/logrus" 28 "github.com/vishvananda/netlink" 29 "github.com/vishvananda/netlink/nl" 30 "github.com/vishvananda/netns" 31 "golang.org/x/sys/unix" 32 ) 33 34 var ( 35 hostMode bool 36 networkOnce sync.Once 37 networkMu sync.Mutex 38 vniTbl = make(map[uint32]string) 39 ) 40 41 type networkTable map[string]*network 42 43 type subnet struct { 44 sboxInit bool 45 vxlanName string 46 brName string 47 vni uint32 48 initErr error 49 subnetIP *net.IPNet 50 gwIP *net.IPNet 51 } 52 53 type subnetJSON struct { 54 SubnetIP string 55 GwIP string 56 Vni uint32 57 } 58 59 type network struct { 60 id string 61 dbIndex uint64 62 dbExists bool 63 sbox osl.Sandbox 64 nlSocket *nl.NetlinkSocket 65 endpoints endpointTable 66 driver *driver 67 joinCnt int 68 sboxInit bool 69 initEpoch int 70 initErr error 71 subnets []*subnet 72 secure bool 73 mtu int 74 sync.Mutex 75 } 76 77 func init() { 78 reexec.Register("set-default-vlan", setDefaultVlan) 79 } 80 81 func setDefaultVlan() { 82 if len(os.Args) < 3 { 83 logrus.Error("insufficient number of arguments") 84 os.Exit(1) 85 } 86 87 runtime.LockOSThread() 88 defer runtime.UnlockOSThread() 89 90 nsPath := os.Args[1] 91 ns, err := netns.GetFromPath(nsPath) 92 if err != nil { 93 logrus.Errorf("overlay namespace get failed, %v", err) 94 os.Exit(1) 95 } 96 if err = netns.Set(ns); err != nil { 97 logrus.Errorf("setting into overlay namespace failed, %v", err) 98 os.Exit(1) 99 } 100 101 // make sure the sysfs mount doesn't propagate back 102 if err = unix.Unshare(unix.CLONE_NEWNS); err != nil { 103 logrus.Errorf("unshare failed, %v", err) 104 os.Exit(1) 105 } 106 107 flag := unix.MS_PRIVATE | unix.MS_REC 108 if err = unix.Mount("", "/", "", uintptr(flag), ""); err != nil { 109 logrus.Errorf("root mount failed, %v", err) 110 os.Exit(1) 111 } 112 113 if err = unix.Mount("sysfs", "/sys", "sysfs", 0, ""); err != nil { 114 logrus.Errorf("mounting sysfs failed, %v", err) 115 os.Exit(1) 116 } 117 118 brName := os.Args[2] 119 path := filepath.Join("/sys/class/net", brName, "bridge/default_pvid") 120 data := []byte{'0', '\n'} 121 122 if err = os.WriteFile(path, data, 0644); err != nil { 123 logrus.Errorf("enabling default vlan on bridge %s failed %v", brName, err) 124 os.Exit(1) 125 } 126 os.Exit(0) 127 } 128 129 func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) { 130 return nil, types.NotImplementedErrorf("not implemented") 131 } 132 133 func (d *driver) NetworkFree(id string) error { 134 return types.NotImplementedErrorf("not implemented") 135 } 136 137 func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error { 138 if id == "" { 139 return fmt.Errorf("invalid network id") 140 } 141 if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" { 142 return types.BadRequestErrorf("ipv4 pool is empty") 143 } 144 145 // Since we perform lazy configuration make sure we try 146 // configuring the driver when we enter CreateNetwork 147 if err := d.configure(); err != nil { 148 return err 149 } 150 151 n := &network{ 152 id: id, 153 driver: d, 154 endpoints: endpointTable{}, 155 subnets: []*subnet{}, 156 } 157 158 vnis := make([]uint32, 0, len(ipV4Data)) 159 if gval, ok := option[netlabel.GenericData]; ok { 160 optMap := gval.(map[string]string) 161 if val, ok := optMap[netlabel.OverlayVxlanIDList]; ok { 162 logrus.Debugf("overlay: Received vxlan IDs: %s", val) 163 vniStrings := strings.Split(val, ",") 164 for _, vniStr := range vniStrings { 165 vni, err := strconv.Atoi(vniStr) 166 if err != nil { 167 return fmt.Errorf("invalid vxlan id value %q passed", vniStr) 168 } 169 170 vnis = append(vnis, uint32(vni)) 171 } 172 } 173 if _, ok := optMap[secureOption]; ok { 174 n.secure = true 175 } 176 if val, ok := optMap[netlabel.DriverMTU]; ok { 177 var err error 178 if n.mtu, err = strconv.Atoi(val); err != nil { 179 return fmt.Errorf("failed to parse %v: %v", val, err) 180 } 181 if n.mtu < 0 { 182 return fmt.Errorf("invalid MTU value: %v", n.mtu) 183 } 184 } 185 } 186 187 // If we are getting vnis from libnetwork, either we get for 188 // all subnets or none. 189 if len(vnis) != 0 && len(vnis) < len(ipV4Data) { 190 return fmt.Errorf("insufficient vnis(%d) passed to overlay", len(vnis)) 191 } 192 193 for i, ipd := range ipV4Data { 194 s := &subnet{ 195 subnetIP: ipd.Pool, 196 gwIP: ipd.Gateway, 197 } 198 199 if len(vnis) != 0 { 200 s.vni = vnis[i] 201 } 202 203 n.subnets = append(n.subnets, s) 204 } 205 206 d.Lock() 207 defer d.Unlock() 208 if d.networks[n.id] != nil { 209 return fmt.Errorf("attempt to create overlay network %v that already exists", n.id) 210 } 211 212 if err := n.writeToStore(); err != nil { 213 return fmt.Errorf("failed to update data store for network %v: %v", n.id, err) 214 } 215 216 // Make sure no rule is on the way from any stale secure network 217 if !n.secure { 218 for _, vni := range vnis { 219 programMangle(vni, false) 220 programInput(vni, false) 221 } 222 } 223 224 if nInfo != nil { 225 if err := nInfo.TableEventRegister(ovPeerTable, driverapi.EndpointObject); err != nil { 226 // XXX Undo writeToStore? No method to so. Why? 227 return err 228 } 229 } 230 231 d.networks[id] = n 232 233 return nil 234 } 235 236 func (d *driver) DeleteNetwork(nid string) error { 237 if nid == "" { 238 return fmt.Errorf("invalid network id") 239 } 240 241 // Make sure driver resources are initialized before proceeding 242 if err := d.configure(); err != nil { 243 return err 244 } 245 246 d.Lock() 247 // Only perform a peer flush operation (if required) AFTER unlocking 248 // the driver lock to avoid deadlocking w/ the peerDB. 249 var doPeerFlush bool 250 defer func() { 251 d.Unlock() 252 if doPeerFlush { 253 d.peerFlush(nid) 254 } 255 }() 256 257 // This is similar to d.network(), but we need to keep holding the lock 258 // until we are done removing this network. 259 n, ok := d.networks[nid] 260 if !ok { 261 n = d.restoreNetworkFromStore(nid) 262 } 263 if n == nil { 264 return fmt.Errorf("could not find network with id %s", nid) 265 } 266 267 for _, ep := range n.endpoints { 268 if ep.ifName != "" { 269 if link, err := ns.NlHandle().LinkByName(ep.ifName); err == nil { 270 if err := ns.NlHandle().LinkDel(link); err != nil { 271 logrus.WithError(err).Warnf("Failed to delete interface (%s)'s link on endpoint (%s) delete", ep.ifName, ep.id) 272 } 273 } 274 } 275 276 if err := d.deleteEndpointFromStore(ep); err != nil { 277 logrus.Warnf("Failed to delete overlay endpoint %.7s from local store: %v", ep.id, err) 278 } 279 } 280 281 doPeerFlush = true 282 delete(d.networks, nid) 283 284 vnis, err := n.releaseVxlanID() 285 if err != nil { 286 return err 287 } 288 289 if n.secure { 290 for _, vni := range vnis { 291 programMangle(vni, false) 292 programInput(vni, false) 293 } 294 } 295 296 return nil 297 } 298 299 func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error { 300 return nil 301 } 302 303 func (d *driver) RevokeExternalConnectivity(nid, eid string) error { 304 return nil 305 } 306 307 func (n *network) joinSandbox(s *subnet, restore bool, incJoinCount bool) error { 308 // If there is a race between two go routines here only one will win 309 // the other will wait. 310 networkOnce.Do(networkOnceInit) 311 312 n.Lock() 313 // If non-restore initialization occurred and was successful then 314 // tell the peerDB to initialize the sandbox with all the peers 315 // previously received from networkdb. But only do this after 316 // unlocking the network. Otherwise we could deadlock with 317 // on the peerDB channel while peerDB is waiting for the network lock. 318 var doInitPeerDB bool 319 defer func() { 320 n.Unlock() 321 if doInitPeerDB { 322 go n.driver.initSandboxPeerDB(n.id) 323 } 324 }() 325 326 if !n.sboxInit { 327 n.initErr = n.initSandbox(restore) 328 doInitPeerDB = n.initErr == nil && !restore 329 // If there was an error, we cannot recover it 330 n.sboxInit = true 331 } 332 333 if n.initErr != nil { 334 return fmt.Errorf("network sandbox join failed: %v", n.initErr) 335 } 336 337 subnetErr := s.initErr 338 if !s.sboxInit { 339 subnetErr = n.initSubnetSandbox(s, restore) 340 // We can recover from these errors, but not on restore 341 if restore || subnetErr == nil { 342 s.initErr = subnetErr 343 s.sboxInit = true 344 } 345 } 346 if subnetErr != nil { 347 return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), subnetErr) 348 } 349 350 if incJoinCount { 351 n.joinCnt++ 352 } 353 354 return nil 355 } 356 357 func (n *network) leaveSandbox() { 358 n.Lock() 359 defer n.Unlock() 360 n.joinCnt-- 361 if n.joinCnt != 0 { 362 return 363 } 364 365 n.destroySandbox() 366 367 n.sboxInit = false 368 n.initErr = nil 369 for _, s := range n.subnets { 370 s.sboxInit = false 371 s.initErr = nil 372 } 373 } 374 375 // to be called while holding network lock 376 func (n *network) destroySandbox() { 377 if n.sbox != nil { 378 for _, iface := range n.sbox.Info().Interfaces() { 379 if err := iface.Remove(); err != nil { 380 logrus.Debugf("Remove interface %s failed: %v", iface.SrcName(), err) 381 } 382 } 383 384 for _, s := range n.subnets { 385 if hostMode { 386 if err := removeFilters(n.id[:12], s.brName); err != nil { 387 logrus.Warnf("Could not remove overlay filters: %v", err) 388 } 389 } 390 391 if s.vxlanName != "" { 392 err := deleteInterface(s.vxlanName) 393 if err != nil { 394 logrus.Warnf("could not cleanup sandbox properly: %v", err) 395 } 396 } 397 } 398 399 if hostMode { 400 if err := removeNetworkChain(n.id[:12]); err != nil { 401 logrus.Warnf("could not remove network chain: %v", err) 402 } 403 } 404 405 // Close the netlink socket, this will also release the watchMiss goroutine that is using it 406 if n.nlSocket != nil { 407 n.nlSocket.Close() 408 n.nlSocket = nil 409 } 410 411 n.sbox.Destroy() 412 n.sbox = nil 413 } 414 } 415 416 func populateVNITbl() { 417 filepath.Walk(filepath.Dir(osl.GenerateKey("walk")), 418 // NOTE(cpuguy83): The linter picked up on the fact that this walk function was not using this error argument 419 // That seems wrong... however I'm not familiar with this code or if that error matters 420 func(path string, info os.FileInfo, _ error) error { 421 _, fname := filepath.Split(path) 422 423 if len(strings.Split(fname, "-")) <= 1 { 424 return nil 425 } 426 427 ns, err := netns.GetFromPath(path) 428 if err != nil { 429 logrus.Errorf("Could not open namespace path %s during vni population: %v", path, err) 430 return nil 431 } 432 defer ns.Close() 433 434 nlh, err := netlink.NewHandleAt(ns, unix.NETLINK_ROUTE) 435 if err != nil { 436 logrus.Errorf("Could not open netlink handle during vni population for ns %s: %v", path, err) 437 return nil 438 } 439 defer nlh.Close() 440 441 err = nlh.SetSocketTimeout(soTimeout) 442 if err != nil { 443 logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vni table population: %v", err) 444 } 445 446 links, err := nlh.LinkList() 447 if err != nil { 448 logrus.Errorf("Failed to list interfaces during vni population for ns %s: %v", path, err) 449 return nil 450 } 451 452 for _, l := range links { 453 if l.Type() == "vxlan" { 454 vniTbl[uint32(l.(*netlink.Vxlan).VxlanId)] = path 455 } 456 } 457 458 return nil 459 }) 460 } 461 462 func networkOnceInit() { 463 populateVNITbl() 464 465 if os.Getenv("_OVERLAY_HOST_MODE") != "" { 466 hostMode = true 467 return 468 } 469 470 err := createVxlan("testvxlan", 1, 0) 471 if err != nil { 472 logrus.Errorf("Failed to create testvxlan interface: %v", err) 473 return 474 } 475 476 defer deleteInterface("testvxlan") 477 478 path := "/proc/self/ns/net" 479 hNs, err := netns.GetFromPath(path) 480 if err != nil { 481 logrus.Errorf("Failed to get network namespace from path %s while setting host mode: %v", path, err) 482 return 483 } 484 defer hNs.Close() 485 486 nlh := ns.NlHandle() 487 488 iface, err := nlh.LinkByName("testvxlan") 489 if err != nil { 490 logrus.Errorf("Failed to get link testvxlan while setting host mode: %v", err) 491 return 492 } 493 494 // If we are not able to move the vxlan interface to a namespace 495 // then fallback to host mode 496 if err := nlh.LinkSetNsFd(iface, int(hNs)); err != nil { 497 hostMode = true 498 } 499 } 500 501 func (n *network) generateVxlanName(s *subnet) string { 502 id := n.id 503 if len(n.id) > 5 { 504 id = n.id[:5] 505 } 506 507 return fmt.Sprintf("vx-%06x-%v", s.vni, id) 508 } 509 510 func (n *network) generateBridgeName(s *subnet) string { 511 id := n.id 512 if len(n.id) > 5 { 513 id = n.id[:5] 514 } 515 516 return n.getBridgeNamePrefix(s) + "-" + id 517 } 518 519 func (n *network) getBridgeNamePrefix(s *subnet) string { 520 return fmt.Sprintf("ov-%06x", s.vni) 521 } 522 523 func checkOverlap(nw *net.IPNet) error { 524 var nameservers []string 525 526 if rc, err := resolvconf.Get(); err == nil { 527 nameservers = resolvconf.GetNameserversAsCIDR(rc.Content) 528 } 529 530 if err := netutils.CheckNameserverOverlaps(nameservers, nw); err != nil { 531 return fmt.Errorf("overlay subnet %s failed check with nameserver: %v: %v", nw.String(), nameservers, err) 532 } 533 534 if err := netutils.CheckRouteOverlaps(nw); err != nil { 535 return fmt.Errorf("overlay subnet %s failed check with host route table: %v", nw.String(), err) 536 } 537 538 return nil 539 } 540 541 func (n *network) restoreSubnetSandbox(s *subnet, brName, vxlanName string) error { 542 sbox := n.sbox 543 544 // restore overlay osl sandbox 545 Ifaces := make(map[string][]osl.IfaceOption) 546 brIfaceOption := make([]osl.IfaceOption, 2) 547 brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Address(s.gwIP)) 548 brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Bridge(true)) 549 Ifaces[brName+"+br"] = brIfaceOption 550 551 err := sbox.Restore(Ifaces, nil, nil, nil) 552 if err != nil { 553 return err 554 } 555 556 Ifaces = make(map[string][]osl.IfaceOption) 557 vxlanIfaceOption := make([]osl.IfaceOption, 1) 558 vxlanIfaceOption = append(vxlanIfaceOption, sbox.InterfaceOptions().Master(brName)) 559 Ifaces[vxlanName+"+vxlan"] = vxlanIfaceOption 560 return sbox.Restore(Ifaces, nil, nil, nil) 561 } 562 563 func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error { 564 if hostMode { 565 // Try to delete stale bridge interface if it exists 566 if err := deleteInterface(brName); err != nil { 567 deleteInterfaceBySubnet(n.getBridgeNamePrefix(s), s) 568 } 569 // Try to delete the vxlan interface by vni if already present 570 deleteVxlanByVNI("", s.vni) 571 572 if err := checkOverlap(s.subnetIP); err != nil { 573 return err 574 } 575 } 576 577 if !hostMode { 578 // Try to find this subnet's vni is being used in some 579 // other namespace by looking at vniTbl that we just 580 // populated in the once init. If a hit is found then 581 // it must a stale namespace from previous 582 // life. Destroy it completely and reclaim resourced. 583 networkMu.Lock() 584 path, ok := vniTbl[s.vni] 585 networkMu.Unlock() 586 587 if ok { 588 deleteVxlanByVNI(path, s.vni) 589 if err := unix.Unmount(path, unix.MNT_FORCE); err != nil { 590 logrus.Errorf("unmount of %s failed: %v", path, err) 591 } 592 os.Remove(path) 593 594 networkMu.Lock() 595 delete(vniTbl, s.vni) 596 networkMu.Unlock() 597 } 598 } 599 600 // create a bridge and vxlan device for this subnet and move it to the sandbox 601 sbox := n.sbox 602 603 if err := sbox.AddInterface(brName, "br", 604 sbox.InterfaceOptions().Address(s.gwIP), 605 sbox.InterfaceOptions().Bridge(true)); err != nil { 606 return fmt.Errorf("bridge creation in sandbox failed for subnet %q: %v", s.subnetIP.String(), err) 607 } 608 609 err := createVxlan(vxlanName, s.vni, n.maxMTU()) 610 if err != nil { 611 return err 612 } 613 614 if err := sbox.AddInterface(vxlanName, "vxlan", 615 sbox.InterfaceOptions().Master(brName)); err != nil { 616 // If adding vxlan device to the overlay namespace fails, remove the bridge interface we 617 // already added to the namespace. This allows the caller to try the setup again. 618 for _, iface := range sbox.Info().Interfaces() { 619 if iface.SrcName() == brName { 620 if ierr := iface.Remove(); ierr != nil { 621 logrus.Errorf("removing bridge failed from ov ns %v failed, %v", n.sbox.Key(), ierr) 622 } 623 } 624 } 625 626 // Also, delete the vxlan interface. Since a global vni id is associated 627 // with the vxlan interface, an orphaned vxlan interface will result in 628 // failure of vxlan device creation if the vni is assigned to some other 629 // network. 630 if deleteErr := deleteInterface(vxlanName); deleteErr != nil { 631 logrus.Warnf("could not delete vxlan interface, %s, error %v, after config error, %v", vxlanName, deleteErr, err) 632 } 633 return fmt.Errorf("vxlan interface creation failed for subnet %q: %v", s.subnetIP.String(), err) 634 } 635 636 if !hostMode { 637 var name string 638 for _, i := range sbox.Info().Interfaces() { 639 if i.Bridge() { 640 name = i.DstName() 641 } 642 } 643 cmd := &exec.Cmd{ 644 Path: reexec.Self(), 645 Args: []string{"set-default-vlan", sbox.Key(), name}, 646 Stdout: os.Stdout, 647 Stderr: os.Stderr, 648 } 649 if err := cmd.Run(); err != nil { 650 // not a fatal error 651 logrus.Errorf("reexec to set bridge default vlan failed %v", err) 652 } 653 } 654 655 if hostMode { 656 if err := addFilters(n.id[:12], brName); err != nil { 657 return err 658 } 659 } 660 661 return nil 662 } 663 664 // Must be called with the network lock 665 func (n *network) initSubnetSandbox(s *subnet, restore bool) error { 666 brName := n.generateBridgeName(s) 667 vxlanName := n.generateVxlanName(s) 668 669 if restore { 670 if err := n.restoreSubnetSandbox(s, brName, vxlanName); err != nil { 671 return err 672 } 673 } else { 674 if err := n.setupSubnetSandbox(s, brName, vxlanName); err != nil { 675 return err 676 } 677 } 678 679 s.vxlanName = vxlanName 680 s.brName = brName 681 682 return nil 683 } 684 685 func (n *network) cleanupStaleSandboxes() { 686 filepath.Walk(filepath.Dir(osl.GenerateKey("walk")), 687 func(path string, info os.FileInfo, err error) error { 688 _, fname := filepath.Split(path) 689 690 pList := strings.Split(fname, "-") 691 if len(pList) <= 1 { 692 return nil 693 } 694 695 pattern := pList[1] 696 if strings.Contains(n.id, pattern) { 697 // Delete all vnis 698 deleteVxlanByVNI(path, 0) 699 unix.Unmount(path, unix.MNT_DETACH) 700 os.Remove(path) 701 702 // Now that we have destroyed this 703 // sandbox, remove all references to 704 // it in vniTbl so that we don't 705 // inadvertently destroy the sandbox 706 // created in this life. 707 networkMu.Lock() 708 for vni, tblPath := range vniTbl { 709 if tblPath == path { 710 delete(vniTbl, vni) 711 } 712 } 713 networkMu.Unlock() 714 } 715 716 return nil 717 }) 718 } 719 720 func (n *network) initSandbox(restore bool) error { 721 n.initEpoch++ 722 723 if !restore { 724 if hostMode { 725 if err := addNetworkChain(n.id[:12]); err != nil { 726 return err 727 } 728 } 729 730 // If there are any stale sandboxes related to this network 731 // from previous daemon life clean it up here 732 n.cleanupStaleSandboxes() 733 } 734 735 // In the restore case network sandbox already exist; but we don't know 736 // what epoch number it was created with. It has to be retrieved by 737 // searching the net namespaces. 738 var key string 739 if restore { 740 key = osl.GenerateKey("-" + n.id) 741 } else { 742 key = osl.GenerateKey(fmt.Sprintf("%d-", n.initEpoch) + n.id) 743 } 744 745 sbox, err := osl.NewSandbox(key, !hostMode, restore) 746 if err != nil { 747 return fmt.Errorf("could not get network sandbox (oper %t): %v", restore, err) 748 } 749 750 // this is needed to let the peerAdd configure the sandbox 751 n.sbox = sbox 752 753 // If we are in swarm mode, we don't need anymore the watchMiss routine. 754 // This will save 1 thread and 1 netlink socket per network 755 if !n.driver.isSerfAlive() { 756 return nil 757 } 758 759 var nlSock *nl.NetlinkSocket 760 sbox.InvokeFunc(func() { 761 nlSock, err = nl.Subscribe(unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH) 762 if err != nil { 763 return 764 } 765 // set the receive timeout to not remain stuck on the RecvFrom if the fd gets closed 766 tv := unix.NsecToTimeval(soTimeout.Nanoseconds()) 767 err = nlSock.SetReceiveTimeout(&tv) 768 }) 769 n.nlSocket = nlSock 770 771 if err == nil { 772 go n.watchMiss(nlSock, key) 773 } else { 774 logrus.Errorf("failed to subscribe to neighbor group netlink messages for overlay network %s in sbox %s: %v", 775 n.id, sbox.Key(), err) 776 } 777 778 return nil 779 } 780 781 func (n *network) watchMiss(nlSock *nl.NetlinkSocket, nsPath string) { 782 // With the new version of the netlink library the deserialize function makes 783 // requests about the interface of the netlink message. This can succeed only 784 // if this go routine is in the target namespace. For this reason following we 785 // lock the thread on that namespace 786 runtime.LockOSThread() 787 defer runtime.UnlockOSThread() 788 newNs, err := netns.GetFromPath(nsPath) 789 if err != nil { 790 logrus.WithError(err).Errorf("failed to get the namespace %s", nsPath) 791 return 792 } 793 defer newNs.Close() 794 if err = netns.Set(newNs); err != nil { 795 logrus.WithError(err).Errorf("failed to enter the namespace %s", nsPath) 796 return 797 } 798 for { 799 msgs, _, err := nlSock.Receive() 800 if err != nil { 801 n.Lock() 802 nlFd := nlSock.GetFd() 803 n.Unlock() 804 if nlFd == -1 { 805 // The netlink socket got closed, simply exit to not leak this goroutine 806 return 807 } 808 // When the receive timeout expires the receive will return EAGAIN 809 if err == unix.EAGAIN { 810 // we continue here to avoid spam for timeouts 811 continue 812 } 813 logrus.Errorf("Failed to receive from netlink: %v ", err) 814 continue 815 } 816 817 for _, msg := range msgs { 818 if msg.Header.Type != unix.RTM_GETNEIGH && msg.Header.Type != unix.RTM_NEWNEIGH { 819 continue 820 } 821 822 neigh, err := netlink.NeighDeserialize(msg.Data) 823 if err != nil { 824 logrus.Errorf("Failed to deserialize netlink ndmsg: %v", err) 825 continue 826 } 827 828 var ( 829 ip net.IP 830 mac net.HardwareAddr 831 l2Miss, l3Miss bool 832 ) 833 if neigh.IP.To4() != nil { 834 ip = neigh.IP 835 l3Miss = true 836 } else if neigh.HardwareAddr != nil { 837 mac = []byte(neigh.HardwareAddr) 838 ip = net.IP(mac[2:]) 839 l2Miss = true 840 } else { 841 continue 842 } 843 844 // Not any of the network's subnets. Ignore. 845 if !n.contains(ip) { 846 continue 847 } 848 849 if neigh.State&(netlink.NUD_STALE|netlink.NUD_INCOMPLETE) == 0 { 850 continue 851 } 852 853 logrus.Debugf("miss notification: dest IP %v, dest MAC %v", ip, mac) 854 mac, IPmask, vtep, err := n.driver.resolvePeer(n.id, ip) 855 if err != nil { 856 logrus.Errorf("could not resolve peer %q: %v", ip, err) 857 continue 858 } 859 n.driver.peerAdd(n.id, "dummy", ip, IPmask, mac, vtep, l2Miss, l3Miss, false) 860 } 861 } 862 } 863 864 // Restore a network from the store to the driver if it is present. 865 // Must be called with the driver locked! 866 func (d *driver) restoreNetworkFromStore(nid string) *network { 867 n := d.getNetworkFromStore(nid) 868 if n != nil { 869 n.driver = d 870 n.endpoints = endpointTable{} 871 d.networks[nid] = n 872 } 873 return n 874 } 875 876 func (d *driver) network(nid string) *network { 877 d.Lock() 878 n, ok := d.networks[nid] 879 if !ok { 880 n = d.restoreNetworkFromStore(nid) 881 } 882 d.Unlock() 883 884 return n 885 } 886 887 func (d *driver) getNetworkFromStore(nid string) *network { 888 if d.store == nil { 889 return nil 890 } 891 892 n := &network{id: nid} 893 if err := d.store.GetObject(datastore.Key(n.Key()...), n); err != nil { 894 return nil 895 } 896 897 return n 898 } 899 900 func (n *network) sandbox() osl.Sandbox { 901 n.Lock() 902 defer n.Unlock() 903 return n.sbox 904 } 905 906 func (n *network) vxlanID(s *subnet) uint32 { 907 n.Lock() 908 defer n.Unlock() 909 return s.vni 910 } 911 912 func (n *network) setVxlanID(s *subnet, vni uint32) { 913 n.Lock() 914 s.vni = vni 915 n.Unlock() 916 } 917 918 func (n *network) Key() []string { 919 return []string{"overlay", "network", n.id} 920 } 921 922 func (n *network) KeyPrefix() []string { 923 return []string{"overlay", "network"} 924 } 925 926 func (n *network) Value() []byte { 927 m := map[string]interface{}{} 928 929 netJSON := []*subnetJSON{} 930 931 for _, s := range n.subnets { 932 sj := &subnetJSON{ 933 SubnetIP: s.subnetIP.String(), 934 GwIP: s.gwIP.String(), 935 Vni: s.vni, 936 } 937 netJSON = append(netJSON, sj) 938 } 939 940 m["secure"] = n.secure 941 m["subnets"] = netJSON 942 m["mtu"] = n.mtu 943 b, err := json.Marshal(m) 944 if err != nil { 945 return []byte{} 946 } 947 948 return b 949 } 950 951 func (n *network) Index() uint64 { 952 return n.dbIndex 953 } 954 955 func (n *network) SetIndex(index uint64) { 956 n.dbIndex = index 957 n.dbExists = true 958 } 959 960 func (n *network) Exists() bool { 961 return n.dbExists 962 } 963 964 func (n *network) Skip() bool { 965 return false 966 } 967 968 func (n *network) SetValue(value []byte) error { 969 var ( 970 m map[string]interface{} 971 newNet bool 972 isMap = true 973 netJSON = []*subnetJSON{} 974 ) 975 976 if err := json.Unmarshal(value, &m); err != nil { 977 err := json.Unmarshal(value, &netJSON) 978 if err != nil { 979 return err 980 } 981 isMap = false 982 } 983 984 if len(n.subnets) == 0 { 985 newNet = true 986 } 987 988 if isMap { 989 if val, ok := m["secure"]; ok { 990 n.secure = val.(bool) 991 } 992 if val, ok := m["mtu"]; ok { 993 n.mtu = int(val.(float64)) 994 } 995 bytes, err := json.Marshal(m["subnets"]) 996 if err != nil { 997 return err 998 } 999 if err := json.Unmarshal(bytes, &netJSON); err != nil { 1000 return err 1001 } 1002 } 1003 1004 for _, sj := range netJSON { 1005 subnetIPstr := sj.SubnetIP 1006 gwIPstr := sj.GwIP 1007 vni := sj.Vni 1008 1009 subnetIP, _ := types.ParseCIDR(subnetIPstr) 1010 gwIP, _ := types.ParseCIDR(gwIPstr) 1011 1012 if newNet { 1013 s := &subnet{ 1014 subnetIP: subnetIP, 1015 gwIP: gwIP, 1016 vni: vni, 1017 } 1018 n.subnets = append(n.subnets, s) 1019 } else { 1020 sNet := n.getMatchingSubnet(subnetIP) 1021 if sNet != nil { 1022 sNet.vni = vni 1023 } 1024 } 1025 } 1026 return nil 1027 } 1028 1029 func (n *network) DataScope() string { 1030 return datastore.GlobalScope 1031 } 1032 1033 func (n *network) writeToStore() error { 1034 if n.driver.store == nil { 1035 return nil 1036 } 1037 1038 return n.driver.store.PutObjectAtomic(n) 1039 } 1040 1041 func (n *network) releaseVxlanID() ([]uint32, error) { 1042 n.Lock() 1043 nSubnets := len(n.subnets) 1044 n.Unlock() 1045 if nSubnets == 0 { 1046 return nil, nil 1047 } 1048 1049 if n.driver.store != nil { 1050 if err := n.driver.store.DeleteObjectAtomic(n); err != nil { 1051 if err == datastore.ErrKeyModified || err == datastore.ErrKeyNotFound { 1052 // In both the above cases we can safely assume that the key has been removed by some other 1053 // instance and so simply get out of here 1054 return nil, nil 1055 } 1056 1057 return nil, fmt.Errorf("failed to delete network to vxlan id map: %v", err) 1058 } 1059 } 1060 var vnis []uint32 1061 n.Lock() 1062 for _, s := range n.subnets { 1063 if n.driver.vxlanIdm != nil { 1064 vnis = append(vnis, s.vni) 1065 } 1066 s.vni = 0 1067 } 1068 n.Unlock() 1069 1070 for _, vni := range vnis { 1071 n.driver.vxlanIdm.Release(uint64(vni)) 1072 } 1073 1074 return vnis, nil 1075 } 1076 1077 func (n *network) obtainVxlanID(s *subnet) error { 1078 // return if the subnet already has a vxlan id assigned 1079 if n.vxlanID(s) != 0 { 1080 return nil 1081 } 1082 1083 if n.driver.store == nil { 1084 return fmt.Errorf("no valid vxlan id and no datastore configured, cannot obtain vxlan id") 1085 } 1086 1087 for { 1088 if err := n.driver.store.GetObject(datastore.Key(n.Key()...), n); err != nil { 1089 return fmt.Errorf("getting network %q from datastore failed %v", n.id, err) 1090 } 1091 1092 if n.vxlanID(s) == 0 { 1093 vxlanID, err := n.driver.vxlanIdm.GetID(true) 1094 if err != nil { 1095 return fmt.Errorf("failed to allocate vxlan id: %v", err) 1096 } 1097 1098 n.setVxlanID(s, uint32(vxlanID)) 1099 if err := n.writeToStore(); err != nil { 1100 n.driver.vxlanIdm.Release(uint64(n.vxlanID(s))) 1101 n.setVxlanID(s, 0) 1102 if err == datastore.ErrKeyModified { 1103 continue 1104 } 1105 return fmt.Errorf("network %q failed to update data store: %v", n.id, err) 1106 } 1107 return nil 1108 } 1109 return nil 1110 } 1111 } 1112 1113 // contains return true if the passed ip belongs to one the network's 1114 // subnets 1115 func (n *network) contains(ip net.IP) bool { 1116 for _, s := range n.subnets { 1117 if s.subnetIP.Contains(ip) { 1118 return true 1119 } 1120 } 1121 1122 return false 1123 } 1124 1125 // getSubnetforIP returns the subnet to which the given IP belongs 1126 func (n *network) getSubnetforIP(ip *net.IPNet) *subnet { 1127 for _, s := range n.subnets { 1128 // first check if the mask lengths are the same 1129 i, _ := s.subnetIP.Mask.Size() 1130 j, _ := ip.Mask.Size() 1131 if i != j { 1132 continue 1133 } 1134 if s.subnetIP.Contains(ip.IP) { 1135 return s 1136 } 1137 } 1138 return nil 1139 } 1140 1141 // getMatchingSubnet return the network's subnet that matches the input 1142 func (n *network) getMatchingSubnet(ip *net.IPNet) *subnet { 1143 if ip == nil { 1144 return nil 1145 } 1146 for _, s := range n.subnets { 1147 // first check if the mask lengths are the same 1148 i, _ := s.subnetIP.Mask.Size() 1149 j, _ := ip.Mask.Size() 1150 if i != j { 1151 continue 1152 } 1153 if s.subnetIP.IP.Equal(ip.IP) { 1154 return s 1155 } 1156 } 1157 return nil 1158 }