struct rnh * zebra_lookup_rnh (struct prefix *p, vrf_id_t vrfid) { struct route_table *table; struct route_node *rn; table = lookup_rnh_table(vrfid, PREFIX_FAMILY(p)); if (!table) return NULL; /* Make it sure prefixlen is applied to the prefix. */ apply_mask (p); /* Lookup route node.*/ rn = route_node_lookup (table, p); if (!rn) return NULL; route_unlock_node (rn); return (rn->info); }
struct rnh * zebra_add_rnh (struct prefix *p, vrf_id_t vrfid) { struct route_table *table; struct route_node *rn; struct rnh *rnh = NULL; if (IS_ZEBRA_DEBUG_NHT) { char buf[INET6_ADDRSTRLEN]; prefix2str(p, buf, INET6_ADDRSTRLEN); zlog_debug("add rnh %s in vrf %d", buf, vrfid); } table = lookup_rnh_table(vrfid, PREFIX_FAMILY(p)); if (!table) { zlog_debug("add_rnh: rnh table not found\n"); return NULL; } /* Make it sure prefixlen is applied to the prefix. */ apply_mask (p); /* Lookup (or add) route node.*/ rn = route_node_get (table, p); if (!rn->info) { rnh = XCALLOC(MTYPE_RNH, sizeof(struct rnh)); rnh->client_list = list_new(); route_lock_node (rn); rn->info = rnh; rnh->node = rn; } route_unlock_node (rn); return (rn->info); }
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; }