/* Tie an interface address to its derived subnet list of addresses. */ int if_subnet_add (struct interface *ifp, struct connected *ifc) { struct route_node *rn; struct zebra_if *zebra_if; struct prefix cp; struct list *addr_list; assert (ifp && ifp->info && ifc); zebra_if = ifp->info; /* Get address derived subnet node and associated address list, while marking address secondary attribute appropriately. */ cp = *ifc->address; apply_mask (&cp); rn = route_node_get (zebra_if->ipv4_subnets, &cp); if ((addr_list = rn->info)) SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY); else { UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY); rn->info = addr_list = list_new (); route_lock_node (rn); } /* Tie address at the tail of address list. */ listnode_add (addr_list, ifc); /* Return list element count. */ return (addr_list->count); }
struct ospf6_lsa * ospf6_lsdb_type_head (u_int16_t type, struct ospf6_lsdb *lsdb) { struct route_node *node; struct prefix_ipv6 key; struct ospf6_lsa *lsa; memset (&key, 0, sizeof (key)); ospf6_lsdb_set_key (&key, &type, sizeof (type)); /* Walk down tree. */ node = lsdb->table->top; while (node && node->p.prefixlen <= key.prefixlen && prefix_match (&node->p, (struct prefix *) &key)) node = node->link[prefix6_bit(&key.prefix, node->p.prefixlen)]; if (node) route_lock_node (node); while (node && node->info == NULL) node = route_next (node); if (node == NULL) return NULL; else route_unlock_node (node); if (! prefix_match ((struct prefix *) &key, &node->p)) return NULL; lsa = node->info; ospf6_lsa_lock (lsa); return lsa; }
static void ospf_ia_network_route (struct ospf *ospf, struct route_table *rt, struct prefix_ipv4 *p, struct ospf_route *new_or, struct ospf_route *abr_or) { struct route_node *rn1; struct ospf_route *or; if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_ia_network_route(): processing summary route to %s/%d", inet_ntoa (p->prefix), p->prefixlen); /* Find a route to the same dest */ if ((rn1 = route_node_lookup (rt, (struct prefix *) p))) { int res; route_unlock_node (rn1); if ((or = rn1->info)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_ia_network_route(): " "Found a route to the same network"); /* Check the existing route. */ if ((res = ospf_route_cmp (ospf, new_or, or)) < 0) { /* New route is better, so replace old one. */ ospf_route_subst (rn1, new_or, abr_or); } else if (res == 0) { /* New and old route are equal, so next hops can be added. */ route_lock_node (rn1); ospf_route_copy_nexthops (or, abr_or->paths); route_unlock_node (rn1); /* new route can be deleted, because existing route has been updated. */ ospf_route_free (new_or); } else { /* New route is worse, so free it. */ ospf_route_free (new_or); return; } } /* if (or)*/ } /*if (rn1)*/ else { /* no route */ if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_ia_network_route(): add new route to %s/%d", inet_ntoa (p->prefix), p->prefixlen); ospf_route_add (rt, p, new_or, abr_or); } }
/* Return the next VRF iterator to the given iterator. */ vrf_iter_t vrf_next (vrf_iter_t iter) { struct route_node *rn = NULL; /* Lock it first because route_next() will unlock it. */ if (iter != VRF_ITER_INVALID) rn = route_next (route_lock_node ((struct route_node *)iter)); for (; rn; rn = route_next (rn)) if (rn->info) { route_unlock_node (rn); /* next */ return (vrf_iter_t)rn; } return VRF_ITER_INVALID; }
static struct route_node *nhrp_route_update_get(const struct prefix *p, int create) { struct route_node *rn; afi_t afi = family2afi(PREFIX_FAMILY(p)); if (!zebra_rib[afi]) return NULL; if (create) { rn = route_node_get(zebra_rib[afi], p); if (!rn->info) { rn->info = XCALLOC(MTYPE_NHRP_ROUTE, sizeof(struct route_info)); route_lock_node(rn); } return rn; } else { return route_node_lookup(zebra_rib[afi], p); } }
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); }
struct ospf6_lsa * ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router, struct ospf6_lsdb *lsdb) { struct route_node *node; struct route_node *matched = NULL; struct prefix_ipv6 key; struct prefix *p; if (lsdb == NULL) return NULL; memset (&key, 0, sizeof (key)); ospf6_lsdb_set_key (&key, &type, sizeof (type)); ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router)); ospf6_lsdb_set_key (&key, &id, sizeof (id)); p = (struct prefix *) &key; { char buf[64]; prefix2str (p, buf, sizeof (buf)); zlog_debug ("lsdb_lookup_next: key: %s", buf); } node = lsdb->table->top; /* walk down tree. */ while (node && node->p.prefixlen <= p->prefixlen && prefix_match (&node->p, p)) { matched = node; node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; } if (matched) node = matched; else node = lsdb->table->top; route_lock_node (node); /* skip to real existing entry */ while (node && node->info == NULL) node = route_next (node); if (! node) return NULL; if (prefix_same (&node->p, p)) { struct route_node *prev = node; struct ospf6_lsa *lsa_prev; struct ospf6_lsa *lsa_next; node = route_next (node); while (node && node->info == NULL) node = route_next (node); lsa_prev = prev->info; lsa_next = (node ? node->info : NULL); assert (lsa_prev); assert (lsa_prev->next == lsa_next); if (lsa_next) assert (lsa_next->prev == lsa_prev); zlog_debug ("lsdb_lookup_next: assert OK with previous LSA"); } if (! node) return NULL; route_unlock_node (node); return (struct ospf6_lsa *) node->info; }
void ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb) { struct prefix_ipv6 key; struct route_node *current, *nextnode, *prevnode; struct ospf6_lsa *next, *prev, *old = NULL; memset (&key, 0, sizeof (key)); ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type)); ospf6_lsdb_set_key (&key, &lsa->header->adv_router, sizeof (lsa->header->adv_router)); ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id)); current = route_node_get (lsdb->table, (struct prefix *) &key); old = current->info; current->info = lsa; ospf6_lsa_lock (lsa); if (old) { if (old->prev) old->prev->next = lsa; if (old->next) old->next->prev = lsa; lsa->next = old->next; lsa->prev = old->prev; } else { /* next link */ nextnode = current; route_lock_node (nextnode); do { nextnode = route_next (nextnode); } while (nextnode && nextnode->info == NULL); if (nextnode == NULL) lsa->next = NULL; else { next = nextnode->info; lsa->next = next; next->prev = lsa; route_unlock_node (nextnode); } /* prev link */ prevnode = current; route_lock_node (prevnode); do { prevnode = route_prev (prevnode); } while (prevnode && prevnode->info == NULL); if (prevnode == NULL) lsa->prev = NULL; else { prev = prevnode->info; lsa->prev = prev; prev->next = lsa; route_unlock_node (prevnode); } lsdb->count++; } if (old) { if (OSPF6_LSA_IS_CHANGED (old, lsa)) { if (OSPF6_LSA_IS_MAXAGE (lsa)) { if (lsdb->hook_remove) { (*lsdb->hook_remove) (old); (*lsdb->hook_remove) (lsa); } } else if (OSPF6_LSA_IS_MAXAGE (old)) { if (lsdb->hook_add) (*lsdb->hook_add) (lsa); } else { if (lsdb->hook_remove) (*lsdb->hook_remove) (old); if (lsdb->hook_add) (*lsdb->hook_add) (lsa); } } } else if (OSPF6_LSA_IS_MAXAGE (lsa)) { if (lsdb->hook_remove) (*lsdb->hook_remove) (lsa); } else { if (lsdb->hook_add) (*lsdb->hook_add) (lsa); } if (old) ospf6_lsa_unlock (old); ospf6_lsdb_count_assert (lsdb); }