func (r *Reloader) Callback(ns namespace.Namespace) error { nsName := ns.Name() vxlanName, err := getVxlanName(nsName) if err != nil { return fmt.Errorf("get vxlan name: %s", err) } err = r.Watcher.StartMonitor(ns, vxlanName) if err != nil { return fmt.Errorf("start monitor: %s", err) } return nil }
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 New( logger lager.Logger, namespace namespace.Namespace, invoker Invoker, linkFactory LinkFactory, watcher watcher.MissWatcher, ) Sandbox { logger = logger.Session("network-sandbox", lager.Data{"namespace": namespace.Name()}) return &NetworkSandbox{ logger: logger, namespace: namespace, invoker: invoker, linkFactory: linkFactory, watcher: watcher, } }
func (w *missWatcher) StopMonitor(ns namespace.Namespace) error { w.Locker.Lock() defer w.Locker.Unlock() logger := w.Logger.Session("stop-monitor", lager.Data{"namespace": ns}) logger.Info("called") defer logger.Info("complete") doneChan, ok := w.DoneChans[ns.Name()] if !ok { err := fmt.Errorf("namespace %s not monitored", ns.Name()) logger.Error("done-channel-missing", err) return err } delete(w.DoneChans, ns.Name()) close(doneChan) return nil }
func (w *missWatcher) StartMonitor(ns namespace.Namespace, vxlanName string) error { logger := w.Logger.Session("start-monitor", lager.Data{"namespace": ns}) logger.Info("called") defer logger.Info("complete") subChan := make(chan *Neigh) unresolvedMisses := make(chan Neighbor) resolvedNeighbors := make(chan Neighbor) doneChan := make(chan struct{}) w.Locker.Lock() w.DoneChans[ns.Name()] = doneChan w.Locker.Unlock() err := w.startARPInserter(ns, vxlanName, resolvedNeighbors) if err != nil { return fmt.Errorf("arp inserter failed: %s", err) } err = w.Subscriber.Subscribe(ns, subChan, doneChan) if err != nil { return fmt.Errorf("subscribe in %s: %s", ns.Name(), err) } go func() { logger := logger.Session("forward-neighbor-messages") logger.Info("starting") for neigh := range subChan { unresolvedMisses <- Neighbor{ SandboxName: ns.Name(), Neigh: *neigh, } } logger.Info("complete") }() go w.Resolver.ResolveMisses(unresolvedMisses, resolvedNeighbors) return nil }
. "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" "github.com/pivotal-golang/lager/lagertest" ) var _ = Describe("Sandbox Consistency", func() { var ( session *gexec.Session ducatiCmd *exec.Cmd address string containerID string vni int sandboxName string sandboxRepoDir string spaceID string appID string networkID string logger *lagertest.TestLogger // sandboxRepo namespace.Repository containerRepo namespace.Repository containerNamespace namespace.Namespace configFilePath string ) BeforeEach(func() { var err error address = fmt.Sprintf("127.0.0.1:%d", 4001+GinkgoParallelNode()) sandboxRepoDir, err = ioutil.TempDir("", "sandbox") Expect(err).NotTo(HaveOccurred())
"github.com/onsi/gomega/gbytes" "github.com/onsi/gomega/gexec" "github.com/pivotal-golang/lager/lagertest" ) var _ = Describe("Networks", func() { var ( session *gexec.Session address string containerID string vni int spaceID string networkID string appID string logger *lagertest.TestLogger sandboxRepo namespace.Repository containerRepo namespace.Repository containerNamespace namespace.Namespace upSpec models.CNIAddPayload downSpec models.CNIDelPayload daemonClient *client.DaemonClient ) BeforeEach(func() { address = fmt.Sprintf("127.0.0.1:%d", 4001+GinkgoParallelNode()) sandboxRepoDir, err := ioutil.TempDir("", "sandbox") Expect(err).NotTo(HaveOccurred())
ns = &fakes.Namespace{} }) It("returns an error", func() { err := repo.Destroy(ns) Expect(err).To(MatchError("namespace is not a Netns")) }) It("logs the failure", func() { repo.Destroy(ns) Expect(logger).To(gbytes.Say("destroy.not-a-netns")) }) }) Context("when the namespace file is not a bind mount", func() { var ns namespace.Namespace BeforeEach(func() { var err error ns, err = repo.Create("already-destroyed") Expect(err).NotTo(HaveOccurred()) err = repo.Destroy(ns) Expect(err).NotTo(HaveOccurred()) f, err := os.Create(ns.Name()) Expect(err).NotTo(HaveOccurred()) f.Close() }) AfterEach(func() {
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 }
daemonConfig.Marshal(configFile) Expect(configFile.Close()).To(Succeed()) return configFile.Name() } var _ = Describe("Networks", func() { var ( session *gexec.Session address string containerID string vni int sandboxName string hostAddress string spaceID string appID string networkID string logger *lagertest.TestLogger sandboxRepo namespace.Repository containerRepo namespace.Repository containerNamespace namespace.Namespace ) BeforeEach(func() { address = fmt.Sprintf("127.0.0.1:%d", 4001+GinkgoParallelNode()) sandboxRepoDir, err := ioutil.TempDir("", "sandbox") Expect(err).NotTo(HaveOccurred()) logger = lagertest.NewTestLogger("test") threadLocker := &ossupport.OSLocker{}