def main(argv): options, args = parse(argv) handle = args[0] src = args[1] dsts = args[2:] getLinks(options) eotx.Node.PACKETSIZE = options.size if(options.cheatlist != '-'): cheatLinks(options) options.linksett = None if(options.metric == 'etx' or options.prune == 'metric-up-fs'): options.linksett = etx.linksETT(options.links, options.backlinks, eotx.Node.PACKETSIZE) if(not options.multicast and len(dsts) == 1): dst = dsts[0] e = eotx.EOTX(options.links, options.linksett) if(not computeUnicast(options, e, src, dst)): return 1 outputUnicast(options, e, src, dst, handle) if(options.loads != ''): outputLoads(options, e, src, dst) if(options.zifile != ''): outputZi(options, e, src, dst) else: assert(options.format == 'more') if(not computeMulticast(options, src, dsts, handle)): return 1 # output procedure return 0
def computeMulticast(options, src, dsts, handle): e = eotx.EOTX(options.links, options.linksett) allnodes = list(e.nodes) # make a copy resilient to pruning # compute individual unicasts and store .tx for each dst unicast = {} # tx[dst], rate, links, next (for TMO ONLY!) for n in allnodes: unicast[n.id] = [ [0.0] * len(dsts), 0, {}, None ] for d in range(len(dsts)): for n in allnodes: n.reset() e.nodes = list(allnodes) # XXX FIXME works only for single rate computeUnicast(options, e, src, dsts[d]) for n in e.nodes: u = unicast[n.id] if(n.rate > 0): u[0][d] = n.tx u[1] = n.rate u[2] = n.links[n.rate] # HACK PART 1 u[3] = n.next.id #print '\n\nUNICAST %d' % d #outputUnicast(options, e, src, dsts[d], handle) #print '\n\nMULTICAST' # determine teaching order et = eotx.EOTX(options.backlinks, etx.linksETT(options.backlinks, None, eotx.Node.PACKETSIZE)) activenodes = [] for n in et.nodes: if(n.id in dsts or sum(unicast[n.id][0]) > 0): activenodes.append(n) et.nodes = activenodes et.setRelaxSingle() et.initMetric(src) et.computeMetric(None) maxmetric = 0.0 for n in et.nodes[::-1]: if(n.metric < eotx.infinity): maxmetric = n.metric break # output # make all links to source 1.0 for n in et.nodes: unicast[n.id][2][src] = 1.0 # then the rest for i in range(len(et.nodes)): ni = et.nodes[i] ui = unicast[ni.id] # print metric rate and pseudo-bcast next hop print '%s.ip %s.set %d %d FF:FF:FF:FF:FF:FF' % (ni.id, handle, int((maxmetric - ni.metric) * options.scale), ui[1]), print rng = i if(i == 0): rng = len(et.nodes) # everyone is "upstream" of source for j in range(rng): nj = et.nodes[j] uj = unicast[nj.id] txj = uj[0] p = uj[2].get(ni.id, 0.0) if(sum(txj) * p > 0.0005): print '%s.ip %s.inflow ' % (ni.id, handle), for d in range(len(dsts)): print '%.3f' % (txj[d] * p), print txi = ui[0] if(sum(txi) > 0.0): # print outflow print '%s.ip %s.outflow ' % (ni.id, handle), for d in range(len(dsts)): print '%.3f' % (txi[d]), print return True