static void foreach_route_cb (struct nl_object *object, void *user_data) { ForeachRouteInfo *info = user_data; struct rtnl_route *route = (struct rtnl_route *) object; struct nl_addr *dst; if (info->out_route) return; if (nm_logging_level_enabled (LOGL_DEBUG)) dump_route (route); if ( info->ifindex > 0 && rtnl_route_get_oif (route) != info->ifindex) return; if ( info->scope != RT_SCOPE_UNIVERSE && rtnl_route_get_scope (route) != info->scope) return; if ( info->family != AF_UNSPEC && rtnl_route_get_family (route) != info->family) return; dst = rtnl_route_get_dst (route); /* Check for IPv6 LL and MC routes that might need to be ignored */ if ( (info->family == AF_INET6 || info->family == AF_UNSPEC) && (rtnl_route_get_family (route) == AF_INET6)) { struct in6_addr *addr = NULL; if (dst) addr = nl_addr_get_binary_addr (dst); if (addr) { if ( IN6_IS_ADDR_LINKLOCAL (addr) || IN6_IS_ADDR_MC_LINKLOCAL (addr) || (IN6_IS_ADDR_MULTICAST (addr) && (nl_addr_get_prefixlen (dst) == 8))) return; } } info->out_route = info->callback (route, dst, info->iface, info->user_data); if (info->out_route) { /* Ref the route so it sticks around after the cache is cleared */ rtnl_route_get (info->out_route); } }
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; }
void dump_pim_mrt(FILE *fp) { grpentry_t *g; mrtentry_t *r; u_int number_of_cache_mirrors = 0; u_int number_of_groups = 0; cand_rp_t *rp; kernel_cache_t *kc; fprintf(fp, "Multicast Routing Table ======================================================\n"); /* TODO: remove the dummy 0.0.0.0 group (first in the chain) */ for (g = grplist->next; g; g = g->next) { number_of_groups++; r = g->grp_route; if (r) { if (r->flags & MRTF_KERNEL_CACHE) { for (kc = r->kernel_cache; kc; kc = kc->next) number_of_cache_mirrors++; } /* Print the (*,G) routing info */ fprintf(fp, "----------------------------------- (*,G) ------------------------------------\n"); fprintf(fp, "Source Group RP Address Flags\n"); fprintf(fp, "--------------- --------------- --------------- ---------------------------\n"); fprintf(fp, "%-15s ", "INADDR_ANY"); fprintf(fp, "%-15s ", inet_fmt(g->group, s1, sizeof(s1))); fprintf(fp, "%-15s ", g->active_rp_grp ? inet_fmt(g->rpaddr, s2, sizeof(s2)) : "NULL"); dump_route(fp, r); } /* Print all (S,G) routing info */ fprintf(fp, "----------------------------------- (S,G) ------------------------------------\n"); for (r = g->mrtlink; r; r = r->grpnext) { if (r->flags & MRTF_KERNEL_CACHE) number_of_cache_mirrors++; /* Print the routing info */ fprintf(fp, "Source Group RP Address Flags\n"); fprintf(fp, "--------------- --------------- --------------- ---------------------------\n"); fprintf(fp, "%-15s ", inet_fmt(r->source->address, s1, sizeof(s1))); fprintf(fp, "%-15s ", inet_fmt(g->group, s2, sizeof(s2))); fprintf(fp, "%-15s ", g->active_rp_grp ? inet_fmt(g->rpaddr, s2, sizeof(s2)) : "NULL"); dump_route(fp, r); } }/* for all groups */ /* Print the (*,*,R) routing entries */ fprintf(fp, "--------------------------------- (*,*,G) ------------------------------------\n"); for (rp = cand_rp_list; rp; rp = rp->next) { r = rp->rpentry->mrtlink; if (r) { if (r->flags & MRTF_KERNEL_CACHE) { for (kc = r->kernel_cache; kc; kc = kc->next) number_of_cache_mirrors++; } /* Print the (*,*,RP) routing info */ fprintf(fp, "Source Group RP Address Flags\n"); fprintf(fp, "--------------- --------------- --------------- ---------------------------\n"); fprintf(fp, "%-15s ", inet_fmt(r->source->address, s1, sizeof(s1))); fprintf(fp, "%-15s ", "INADDR_ANY"); fprintf(fp, "%-15s ", ""); dump_route(fp, r); } } /* For all (*,*,RP) */ fprintf(fp, "Number of Groups: %u\n", number_of_groups); fprintf(fp, "Number of Cache MIRRORs: %u\n", number_of_cache_mirrors); fprintf(fp, "------------------------------------------------------------------------------\n\n"); }