Пример #1
0
// provisionNode allocates the IDs for one node, meant to be called from a tree
// traversal. If allocation fails, panic and expect to be recovered. The
// allocated IDs are stored in newIds so as to be collected in the recover
// routine.
func provisionNode(g canvas.Graph, this canvas.Node, newIds *[]canvas.NodeIfc) {
	Info.Printf("Provisioning %s (%d)\n", this, this.ID())
	for _, t := range g.From(this) {
		e := g.E(this, t)
		target := t.(canvas.Node)
		chain := computeChainFrom(this, target)
		fid, tid := e.F().Ifc(), e.T().Ifc()
		var err error
		if fid < 0 {
			if fid, err = e.From().(canvas.Node).NewInterfaceID(); err != nil {
				Error.Printf("Provisioning %s failed %s\n", e.From().(canvas.Node), err)
				panic(err)
			}
			*newIds = append(*newIds, canvas.NodeIfc{e.From().ID(), fid})
		}
		if tid < 0 {
			if tid, err = e.To().(canvas.Node).NewInterfaceID(); err != nil {
				Error.Printf("Provisioning %s failed %s\n", e.To().(canvas.Node), err)
				panic(err)
			}
			*newIds = append(*newIds, canvas.NodeIfc{e.To().ID(), tid})
		}
		if e.Update(chain, fid, tid) {
		}
	}
}
Пример #2
0
func computeChainFrom(from, to canvas.Node) (chain []canvas.NodeIfc) {
	// For each link, there is a chain of modules to be invoked: the
	// ingress policy modules, the egress policy modules, and the final
	// forwarding nexthop.
	//
	// To compute the chain in each direction, the following algorithm is
	// followed:
	//  Let T and F represent the set of groups for the 'to' and 'from'
	//   nodes, respectively.
	//  The leaving set L is the set difference between F and T.
	//  L := F - T
	//  The entering set E is the set difference between T and F
	//  E := T - F
	//
	// For the directed edge from:to, the chain is built as follows:
	//  For each module e in E, invoke the ingress policy (e.ifc[1])
	//  For each module l in L, invoke the egress policy (l.ifc[2])
	//
	// The directed edge to:from is calculated by calling this function
	// with to/from reversed.

	var e, l, x intsets.Sparse
	l.Difference(from.Groups(), to.Groups())
	e.Difference(to.Groups(), from.Groups())

	var id int

	x.Copy(&e)
	for x.TakeMin(&id) {
		chain = append(chain, canvas.NodeIfc{id, 1})
	}
	x.Copy(&l)
	for x.TakeMin(&id) {
		chain = append(chain, canvas.NodeIfc{id, 2})
	}
	return chain
}