func (a *ARPInserter) HandleResolvedNeighbors(ready chan error, ns namespace.Namespace, vxlanDeviceName string, resolvedChan <-chan watcher.Neighbor) { var vxlanLink netlink.Link err := ns.Execute(func(f *os.File) error { var err error vxlanLink, err = a.Netlinker.LinkByName(vxlanDeviceName) if err != nil { return fmt.Errorf("find link %q: %s", vxlanDeviceName, err) } return nil }) if err != nil { ready <- fmt.Errorf("namespace execute failed: %s", err) close(ready) return } close(ready) a.addNeighbors(vxlanLink.Attrs().Index, ns, resolvedChan) }
func (a *ARPInserter) addNeighbors(vxlanLinkIndex int, ns namespace.Namespace, resolvedChan <-chan watcher.Neighbor) { for msg := range resolvedChan { neigh := reverseConvert(msg.Neigh) neigh.State = netlink.NUD_REACHABLE fdb := &netlink.Neigh{ LinkIndex: vxlanLinkIndex, HardwareAddr: neigh.HardwareAddr, IP: msg.VTEP, Family: syscall.AF_BRIDGE, Flags: netlink.NTF_SELF, State: netlink.NUD_REACHABLE, } a.Logger.Info("adding-neigbor", lager.Data{ "neigh": neigh.String(), "fdb": fdb, "hw_addr": neigh.HardwareAddr.String(), }) err := ns.Execute(func(*os.File) error { err := a.Netlinker.SetNeigh(neigh) if err != nil { return fmt.Errorf("set L3 neighbor failed: %s", err) } err = a.Netlinker.SetNeigh(fdb) if err != nil { return fmt.Errorf("set L2 forward failed: %s", err) } return nil }) if err != nil { a.Logger.Error("add-neighbor-failed", err) } } }
func (s *Subscriber) Subscribe( sandboxNS namespace.Namespace, neighChan chan<- *watcher.Neigh, doneChan <-chan struct{}, ) error { logger := s.Logger.Session("subscribe") logger.Info("called") defer logger.Info("complete") var sock nl.NLSocket err := sandboxNS.Execute(func(*os.File) error { var err error sock, err = s.Netlinker.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH) if err != nil { logger.Error("netlink-subscribe-failed", err) return fmt.Errorf("failed to acquire netlink socket: %s", err) } return nil }) if err != nil { return fmt.Errorf("namespace execute: %s", err) } go func() { <-doneChan logger.Info("closing-netlink-socket") sock.Close() logger.Info("closed-netlink-socket") }() go func() { defer func() { logger.Info("closing-neigh-chan") close(neighChan) logger.Info("closed-neigh-chan") }() for { msgs, err := sock.Receive() logger.Info("receive-message-count", lager.Data{"message-count": len(msgs)}) if err != nil { s.Logger.Error("socket-receive", err) return } for _, m := range msgs { n, err := s.Netlinker.NeighDeserialize(m.Data) if err != nil { s.Logger.Error("neighbor-deserialize", err) return } if n.IP == nil || (n.HardwareAddr != nil && n.State != netlink.NUD_STALE) { continue } neigh := convertNeigh(n) neighChan <- neigh } } }() return nil }
ContainerNamespace: containerNamespace.Name(), ContainerID: containerID, } By("adding the container to a network") _, err = daemonClient.ContainerUp(upSpec) Expect(err).NotTo(HaveOccurred()) }) AfterEach(func() { By("removing the container from the network") Expect(daemonClient.ContainerDown(downSpec)).To(Succeed()) session.Interrupt() Eventually(session, DEFAULT_TIMEOUT).Should(gexec.Exit(0)) Expect(containerRepo.Destroy(containerNamespace)).To(Succeed()) }) It("catches L3 misses", func() { time.Sleep(2 * time.Second) err := containerNamespace.Execute(func(_ *os.File) error { _, err := net.DialTimeout("tcp", "192.168.1.100:1234", 1*time.Second) Expect(err).To(HaveOccurred()) return nil }) Expect(err).NotTo(HaveOccurred()) Eventually(session.Out, "5s").Should(gbytes.Say("ducatid.sandbox-miss.*dest_ip.*192.168.1.100.*sandbox.*vni-%d", vni)) }) })
By("removing the container from the network") Expect(daemonClient.ContainerDown(downSpec)).To(Succeed()) By("checking that containers have been removed") containers, err := daemonClient.ListNetworkContainers(networkID) Expect(err).NotTo(HaveOccurred()) Expect(containers).To(HaveLen(0)) By("checking that the sandbox has been cleaned up") _, err = sandboxRepo.Get(sandboxName) Expect(err).To(MatchError(ContainSubstring("no such file or directory"))) By("checking that the veth device is no longer in the container") err = containerNamespace.Execute(func(_ *os.File) error { _, err := netlink.LinkByName("vx-eth0") Expect(err).To(MatchError(ContainSubstring("Link not found"))) return nil }) Expect(err).NotTo(HaveOccurred()) }) It("makes container metadata available on the list network containers endpoint", func() { containers, err := daemonClient.ListNetworkContainers(networkID) Expect(err).NotTo(HaveOccurred()) Expect(containers).To(HaveLen(1)) Expect(containers[0].HostIP).To(Equal(hostAddress)) }) It("makes container metadata available on the /containers endpoint", func() { containers, err := daemonClient.ListContainers()