/* Check wether connected is within the ripng_enable_network table. */ static int ripng_enable_network_lookup2 (struct connected *connected) { struct prefix_ipv6 address; struct prefix *p; p = connected->address; if (p->family == AF_INET6) { struct route_node *node; address.family = p->family; address.prefix = p->u.prefix6; address.prefixlen = IPV6_MAX_BITLEN; /* LPM on p->family, p->u.prefix6/IPV6_MAX_BITLEN within ripng_enable_network */ node = route_node_match (ripng_enable_network, (struct prefix *)&address); if (node) { route_unlock_node (node); return 1; } } return -1; }
/* Check wether the interface has at least a connected prefix that * is within the ripng_enable_network table. */ static int ripng_enable_network_lookup_if (struct interface *ifp) { struct listnode *node; struct connected *connected; struct prefix_ipv6 address; for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected)) { struct prefix *p; struct route_node *node; p = connected->address; if (p->family == AF_INET6) { address.family = AF_INET6; address.prefix = p->u.prefix6; address.prefixlen = IPV6_MAX_BITLEN; node = route_node_match (ripng_enable_network, (struct prefix *)&address); if (node) { route_unlock_node (node); return 1; } } } return -1; }
/* Check wether the interface has at least a connected prefix that * is within the ripng_enable_network table. */ int ripng_enable_network_lookup_if (struct interface *ifp) { struct listnode *listnode; struct connected *connected; struct prefix_ipv6 address; for (listnode = listhead (ifp->connected); listnode; nextnode (listnode)) if ((connected = getdata (listnode)) != NULL) { struct prefix *p; struct route_node *node; p = connected->address; if (p->family == AF_INET6) { address.family = AF_INET6; address.prefix = p->u.prefix6; address.prefixlen = IPV6_MAX_BITLEN; node = route_node_match (ripng_enable_network, (struct prefix *)&address); if (node) { route_unlock_node (node); return 1; } } } return -1; }
struct ospf_area_range * ospf_area_range_match (struct ospf_area *area, struct prefix_ipv4 *p) { struct route_node *node; node = route_node_match (area->ranges, (struct prefix *) p); if (node) { route_unlock_node (node); return node->info; } return NULL; }
int nhrp_route_get_nexthop(const union sockunion *addr, struct prefix *p, union sockunion *via, struct interface **ifp) { struct route_node *rn; struct route_info *ri; struct prefix lookup; afi_t afi = family2afi(sockunion_family(addr)); char buf[PREFIX_STRLEN]; sockunion2hostprefix(addr, &lookup); rn = route_node_match(zebra_rib[afi], &lookup); if (!rn) return 0; ri = rn->info; if (ri->nhrp_ifp) { debugf(NHRP_DEBUG_ROUTE, "lookup %s: nhrp_if=%s", prefix2str(&lookup, buf, sizeof buf), ri->nhrp_ifp->name); if (via) sockunion_family(via) = AF_UNSPEC; if (ifp) *ifp = ri->nhrp_ifp; } else { debugf(NHRP_DEBUG_ROUTE, "lookup %s: zebra route dev %s", prefix2str(&lookup, buf, sizeof buf), ri->ifp ? ri->ifp->name : "(none)"); if (via) *via = ri->via; if (ifp) *ifp = ri->ifp; } if (p) *p = rn->p; route_unlock_node(rn); return 1; }
int zebra_evaluate_rnh_table (vrf_id_t vrfid, int family) { struct route_table *ptable; struct route_table *ntable; struct route_node *prn; struct route_node *nrn; struct rnh *rnh; struct zserv *client; struct listnode *node; struct rib *rib; ntable = lookup_rnh_table(vrfid, family); if (!ntable) { zlog_debug("evaluate_rnh_table: rnh table not found\n"); return -1; } ptable = zebra_vrf_table(family2afi(family), SAFI_UNICAST, vrfid); if (!ptable) { zlog_debug("evaluate_rnh_table: prefix table not found\n"); return -1; } for (nrn = route_top (ntable); nrn; nrn = route_next (nrn)) { if (!nrn->info) continue; rnh = nrn->info; prn = route_node_match(ptable, &nrn->p); if (!prn) rib = NULL; else { RNODE_FOREACH_RIB(prn, rib) { if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) continue; if (! CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) continue; if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) { if (rib->type == ZEBRA_ROUTE_CONNECT) break; if (rib->type == ZEBRA_ROUTE_NHRP) { struct nexthop *nexthop; for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) if (nexthop->type == NEXTHOP_TYPE_IFINDEX || nexthop->type == NEXTHOP_TYPE_IFNAME) break; if (nexthop) break; } } else break; } } if (compare_state(rib, rnh->state)) { if (IS_ZEBRA_DEBUG_NHT) { char bufn[INET6_ADDRSTRLEN]; char bufp[INET6_ADDRSTRLEN]; prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); if (prn) prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN); else strcpy(bufp, "null"); zlog_debug("rnh %s resolved through route %s - sending " "nexthop %s event to clients", bufn, bufp, rib ? "reachable" : "unreachable"); } copy_state(rnh, rib); for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) send_client(rnh, client, vrfid); } } return 1; }