Esempio n. 1
0
void
dot_sameports (graph_t* g)
/* merge edge ports in G */
{
  node_t *n;
  edge_t *e;
  char   *id;
  same_t same[MAXSAME];
  int    i;

  E_samehead = agfindattr(g->proto->e,"samehead");
  E_sametail = agfindattr(g->proto->e,"sametail");
  if (!(E_samehead || E_sametail)) return;
  for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
    n_same = 0;
    for (e = agfstedge(g,n); e; e = agnxtedge(g,e,n)) {
      if (e->head==n && E_samehead &&
          (id = agxget (e, E_samehead->index))[0])
        sameedge (same, n, e, id);
      else if (e->tail==n && E_sametail &&
               (id = agxget (e, E_sametail->index))[0])
        sameedge (same, n, e, id);
    }
    for (i=0; i<n_same; i++) {
      if (same[i].l.size>1) sameport (n, &same[i].l, same[i].arr_len);
      free_list(same[i].l);
      /* I sure hope I don't need to free the char* id */
    }
  }
}
Esempio n. 2
0
static int find_route(ib_portid_t * from, ib_portid_t * to, int dump)
{
	Node *node, fromnode, tonode, nextnode;
	Port *port, fromport, toport, nextport;
	Switch sw;
	int maxhops = MAXHOPS;
	int portnum, outport;

	DEBUG("from %s", portid2str(from));

	if (get_node(&fromnode, &fromport, from) < 0 ||
	    get_node(&tonode, &toport, to) < 0) {
		IBWARN("can't reach to/from ports");
		if (!force)
			return -1;
		if (to->lid > 0)
			toport.lid = to->lid;
		IBWARN("Force: look for lid %d", to->lid);
	}

	node = &fromnode;
	port = &fromport;
	portnum = port->portnum;

	dump_endnode(dump, "From", node, port);

	while (maxhops--) {
		if (port->state != 4)
			goto badport;

		if (sameport(port, &toport))
			break;	/* found */

		outport = portnum;
		if (node->type == IB_NODE_SWITCH) {
			DEBUG("switch node");
			if ((outport = switch_lookup(&sw, from, to->lid)) < 0 ||
			    outport > node->numports)
				goto badtbl;

			if (extend_dpath(&from->drpath, outport) < 0)
				goto badpath;

			if (get_node(&nextnode, &nextport, from) < 0) {
				IBWARN("can't reach port at %s",
				       portid2str(from));
				return -1;
			}
			if (outport == 0) {
				if (!sameport(&nextport, &toport))
					goto badtbl;
				else
					break;	/* found SMA port */
			}
		} else if ((node->type == IB_NODE_CA) ||
			   (node->type == IB_NODE_ROUTER)) {
			int ca_src = 0;

			DEBUG("ca or router node");
			if (!sameport(port, &fromport)) {
				IBWARN
				    ("can't continue: reached CA or router port %"
				     PRIx64 ", lid %d", port->portguid,
				     port->lid);
				return -1;
			}
			/* we are at CA or router "from" - go one hop back to (hopefully) a switch */
			if (from->drpath.cnt > 0) {
				DEBUG("ca or router node - return back 1 hop");
				from->drpath.cnt--;
			} else {
				ca_src = 1;
				if (portnum
				    && extend_dpath(&from->drpath, portnum) < 0)
					goto badpath;
			}
			if (get_node(&nextnode, &nextport, from) < 0) {
				IBWARN("can't reach port at %s",
				       portid2str(from));
				return -1;
			}
			/* fix port num to be seen from the CA or router side */
			if (!ca_src)
				nextport.portnum =
				    from->drpath.p[from->drpath.cnt + 1];
		}
		port = &nextport;
		if (port->state != 4)
			goto badoutport;
		node = &nextnode;
		portnum = port->portnum;
		dump_route(dump, node, outport, port);
	}

	if (maxhops <= 0) {
		IBWARN("no route found after %d hops", MAXHOPS);
		return -1;
	}
	dump_endnode(dump, "To", node, port);
	return 0;

badport:
	IBWARN("Bad port state found: node \"%s\" port %d state %d",
	       clean_nodedesc(node->nodedesc), portnum, port->state);
	return -1;
badoutport:
	IBWARN("Bad out port state found: node \"%s\" outport %d state %d",
	       clean_nodedesc(node->nodedesc), outport, port->state);
	return -1;
badtbl:
	IBWARN
	    ("Bad forwarding table entry found at: node \"%s\" lid entry %d is %d (top %d)",
	     clean_nodedesc(node->nodedesc), to->lid, outport, sw.linearFDBtop);
	return -1;
badpath:
	IBWARN("Direct path too long!");
	return -1;
}