Example #1
0
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(),
	}}
}
Example #2
0
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
}