func (s *HoverServer) handleLinkPost(r *http.Request) routeResponse { var req linkEntry if err := json.NewDecoder(r.Body).Decode(&req); err != nil { panic(err) } from := s.lookupNode(req.From) to := s.lookupNode(req.To) if s.g.HasEdgeBetween(from, to) { panic(fmt.Errorf("Link already exists between %q and %q", from, to)) } if from.ID() < 0 { from.SetID(s.g.NewNodeID()) s.g.AddNode(from) } if to.ID() < 0 { to.SetID(s.g.NewNodeID()) s.g.AddNode(to) } fid, tid := -1, -1 e1 := canvas.NewEdgeChain(from, to, &fid, &tid) s.g.SetEdge(e1) e2 := canvas.NewEdgeChain(to, from, &tid, &fid) s.g.SetEdge(e2) s.recomputePolicies() return routeResponse{body: linkEntry{ Id: e1.ID(), From: e1.From().(canvas.Node).Path(), To: e1.To().(canvas.Node).Path(), FromId: e1.F().Ifc(), ToId: e1.T().Ifc(), }} }
func (nm *NetlinkMonitor) handleMasterChange(node *ExtInterface, link netlink.Link, isAdd bool) error { newMasterIdx := link.Attrs().MasterIndex Debug.Printf("link %s master %d\n", node.Link().Attrs().Name, newMasterIdx) if newMasterIdx != node.Link().Attrs().MasterIndex || isAdd { if newMasterIdx != 0 { // add case masterLink, err := netlink.LinkByIndex(newMasterIdx) if err != nil { return err } bridge, ok := masterLink.(*netlink.Bridge) if !ok { return fmt.Errorf("unsupported non-bridge master") } master := nm.ensureBridge(bridge) if node.ID() < 0 { node.SetID(nm.g.NewNodeID()) nm.g.AddNode(node) } // set to 0 so that the normal egress path is taken fid, tid := 0, 0 nm.g.SetEdge(canvas.NewEdgeChain(node, master, &fid, &tid)) nm.g.SetEdge(canvas.NewEdgeChain(master, node, &tid, &fid)) if err := nm.r.Provision(nm.g, []InterfaceNode{node}); err != nil { return err } if err := nm.ensureInterface(nm.g, node); err != nil { return err } nm.r.Run(nm.g, []InterfaceNode{node}) } else { // remove case } } return nil }