/* Delete specified OSPF neighbor from interface. */ void ospf_nbr_delete (struct ospf_neighbor *nbr) { struct ospf_interface *oi; struct route_node *rn; struct prefix p; oi = nbr->oi; /* Unlink ospf neighbor from the interface. */ p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; p.u.prefix4 = nbr->src; rn = route_node_lookup (oi->nbrs, &p); if (rn) { if (rn->info) { rn->info = NULL; route_unlock_node (rn); } else zlog_info ("Can't find neighbor %s in the interface %s", inet_ntoa (nbr->src), IF_NAME (oi)); route_unlock_node (rn); } /* Free ospf_neighbor structure. */ ospf_nbr_free (nbr); }
void isis_redist_delete(int type, struct prefix *p) { int family = p->family; struct route_table *ei_table = get_ext_info(isis, family); struct route_node *ei_node; struct listnode *node; struct isis_area *area; int level; struct isis_redist *redist; char debug_buf[BUFSIZ]; prefix2str(p, debug_buf, sizeof(debug_buf)); zlog_debug("%s: Removing route %s from %s.", __func__, debug_buf, zebra_route_string(type)); if (is_default(p)) { /* Don't remove default route but add synthetic route for use * by "default-information originate always". Areas without the * "always" setting will ignore routes with origin DEFAULT_ROUTE. */ isis_redist_add(DEFAULT_ROUTE, p, 254, MAX_WIDE_PATH_METRIC); return; } if (!ei_table) { zlog_warn("%s: External information table not initialized.", __func__); return; } ei_node = route_node_lookup(ei_table, p); if (!ei_node || !ei_node->info) { char buf[BUFSIZ]; prefix2str(p, buf, sizeof(buf)); zlog_warn("%s: Got a delete for %s route %s, but that route" " was never added.", __func__, zebra_route_string(type), buf); if (ei_node) route_unlock_node(ei_node); return; } route_unlock_node(ei_node); for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) for (level = 1; level < ISIS_LEVELS; level++) { redist = get_redist_settings(area, family, type, level); if (!redist->redist) continue; isis_redist_uninstall(area, level, p); } XFREE(MTYPE_ISIS, ei_node->info); route_unlock_node(ei_node); }
void ospf_free_if_params (struct interface *ifp, struct in_addr addr) { struct ospf_if_params *oip; struct prefix_ipv4 p; struct route_node *rn; p.family = AF_INET; p.prefixlen = IPV4_MAX_PREFIXLEN; p.prefix = addr; rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p); if (!rn || !rn->info) return; oip = rn->info; route_unlock_node (rn); if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) && !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) && !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) && !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) && !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) && !OSPF_IF_PARAM_CONFIGURED (oip, fast_hello) && !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) && !OSPF_IF_PARAM_CONFIGURED (oip, priority) && !OSPF_IF_PARAM_CONFIGURED (oip, type) && !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) && !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) && listcount (oip->auth_crypt) == 0) { ospf_del_if_params (oip); rn->info = NULL; route_unlock_node (rn); } }
void ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb) { struct route_node *node; struct prefix_ipv6 key; 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)); node = route_node_lookup (lsdb->table, (struct prefix *) &key); assert (node && node->info == lsa); if (lsa->prev) lsa->prev->next = lsa->next; if (lsa->next) lsa->next->prev = lsa->prev; node->info = NULL; lsdb->count--; if (lsdb->hook_remove) (*lsdb->hook_remove) (lsa); ospf6_lsa_unlock (lsa); route_unlock_node (node); ospf6_lsdb_count_assert (lsdb); }
/* Remove external reachability information from a * specific area for a specific level. * Schedule an lsp regenerate if necessary. */ static void isis_redist_uninstall(struct isis_area *area, int level, struct prefix *p) { int family = p->family; struct route_table *er_table = get_ext_reach(area, family, level); struct route_node *er_node; if (!er_table) { zlog_warn("%s: External reachability table of area %s" " is not initialized.", __func__, area->area_tag); return; } er_node = route_node_lookup(er_table, p); if (!er_node) return; else route_unlock_node(er_node); if (!er_node->info) return; XFREE(MTYPE_ISIS, er_node->info); route_unlock_node(er_node); lsp_regenerate_schedule(area, level, 0); }
/* lookup nbr by address - use this only if you know you must * otherwise use the ospf_nbr_lookup() wrapper, which deals * with virtual link neighbours */ struct ospf_neighbor *ospf_nbr_lookup_by_addr(struct route_table *nbrs, struct in_addr *addr) { struct prefix p; struct route_node *rn; struct ospf_neighbor *nbr; p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; p.u.prefix4 = *addr; rn = route_node_lookup(nbrs, &p); if (!rn) return NULL; /* See comment in ospf_nbr_delete */ assert(rn->info); if (rn->info == NULL) { route_unlock_node(rn); return NULL; } nbr = (struct ospf_neighbor *)rn->info; route_unlock_node(rn); return nbr; }
/* Check LSA is related to external info. */ struct external_info * ospf_external_info_check (struct ospf_lsa *lsa) { struct as_external_lsa *al; struct prefix_ipv4 p; struct route_node *rn; int type; al = (struct as_external_lsa *) lsa->data; p.family = AF_INET; p.prefix = lsa->data->id; p.prefixlen = ip_masklen (al->mask); for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { int redist_type = is_prefix_default (&p) ? DEFAULT_ROUTE : type; if (ospf_is_type_redistributed (redist_type)) if (EXTERNAL_INFO (type)) { rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p); if (rn) { route_unlock_node (rn); if (rn->info != NULL) return (struct external_info *) rn->info; } } } return NULL; }
/* Delete specified OSPF neighbor from interface. */ void ospf_nbr_delete(struct ospf_neighbor *nbr) { struct ospf_interface *oi; struct route_node *rn; struct prefix p; oi = nbr->oi; /* get appropriate prefix 'key' */ ospf_nbr_key(oi, nbr, &p); rn = route_node_lookup(oi->nbrs, &p); if (rn) { /* If lookup for a NBR succeeds, the leaf route_node could * only exist because there is (or was) a nbr there. * If the nbr was deleted, the leaf route_node should have * lost its last refcount too, and be deleted. * Therefore a looked-up leaf route_node in nbrs table * should never have NULL info. */ assert(rn->info); if (rn->info) { rn->info = NULL; route_unlock_node(rn); } else zlog_info("Can't find neighbor %s in the interface %s", inet_ntoa(nbr->src), IF_NAME(oi)); route_unlock_node(rn); } /* Free ospf_neighbor structure. */ ospf_nbr_free(nbr); }
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); } }
static struct ospf6_damp_info * ospf6_damp_lookup (u_short type, struct prefix *name) { struct route_node *node; node = route_node_lookup (damp_info_table[type], name); if (node && node->info) return (struct ospf6_damp_info *) node->info; return NULL; }
/* Check LSA is related to external info. */ struct external_info *ospf_external_info_check(struct ospf *ospf, struct ospf_lsa *lsa) { struct as_external_lsa *al; struct prefix_ipv4 p; struct route_node *rn; int type; al = (struct as_external_lsa *)lsa->data; p.family = AF_INET; p.prefix = lsa->data->id; p.prefixlen = ip_masklen(al->mask); for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { int redist_on = 0; redist_on = is_prefix_default(&p) ? vrf_bitmap_check(zclient->default_information, ospf->vrf_id) : (zclient->mi_redist[AFI_IP][type].enabled || vrf_bitmap_check( zclient->redist[AFI_IP][type], ospf->vrf_id)); // Pending: check for MI above. if (redist_on) { struct list *ext_list; struct listnode *node; struct ospf_external *ext; ext_list = ospf->external[type]; if (!ext_list) continue; for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { rn = NULL; if (ext->external_info) rn = route_node_lookup( ext->external_info, (struct prefix *)&p); if (rn) { route_unlock_node(rn); if (rn->info != NULL) return (struct external_info *) rn->info; } } } } return NULL; }
static int ospf_interface_address_delete (int command, struct zclient *zclient, zebra_size_t length) { struct ospf *ospf; struct connected *c; struct interface *ifp; struct ospf_interface *oi; struct route_node *rn; struct prefix p; c = zebra_interface_address_read (command, zclient->ibuf); if (c == NULL) return 0; if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) { char buf[128]; prefix2str(c->address, buf, sizeof(buf)); zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf); } ifp = c->ifp; p = *c->address; p.prefixlen = IPV4_MAX_PREFIXLEN; rn = route_node_lookup (IF_OIFS (ifp), &p); if (!rn) { connected_free (c); return 0; } assert (rn->info); oi = rn->info; /* Call interface hook functions to clean up */ ospf_if_free (oi); #ifdef HAVE_SNMP ospf_snmp_if_update (c->ifp); #endif /* HAVE_SNMP */ connected_free (c); ospf = ospf_lookup (); if (ospf != NULL) ospf_if_update (ospf); return 0; }
struct ospf_area_range * ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p) { struct route_node *rn; rn = route_node_lookup (area->ranges, (struct prefix *)p); if (rn) { route_unlock_node (rn); return rn->info; } return NULL; }
/* Look up a VRF by identifier. */ static struct vrf * vrf_lookup (vrf_id_t vrf_id) { struct prefix p; struct route_node *rn; struct vrf *vrf = NULL; vrf_build_key (vrf_id, &p); rn = route_node_lookup (vrf_table, &p); if (rn) { vrf = (struct vrf *)rn->info; route_unlock_node (rn); /* lookup */ } return vrf; }
static void ospf_delete_from_if (struct interface *ifp, struct ospf_interface *oi) { struct route_node *rn; struct prefix p; p = *oi->address; p.prefixlen = IPV4_MAX_PREFIXLEN; rn = route_node_lookup (IF_OIFS (oi->ifp), &p); assert (rn); assert (rn->info); rn->info = NULL; route_unlock_node (rn); route_unlock_node (rn); }
/* lookup oi for specified prefix/ifp */ struct ospf_interface *ospf_if_table_lookup(struct interface *ifp, struct prefix *prefix) { struct prefix p; struct route_node *rn; struct ospf_interface *rninfo = NULL; p = *prefix; p.prefixlen = IPV4_MAX_PREFIXLEN; /* route_node_get implicitely locks */ if ((rn = route_node_lookup(IF_OIFS(ifp), &p))) { rninfo = (struct ospf_interface *)rn->info; route_unlock_node(rn); } return rninfo; }
void ospf_area_range_delete (struct ospf_area *area, struct ospf_area_range *range) { struct route_node *rn; struct prefix_ipv4 p; p.family = AF_INET; p.prefixlen = range->masklen; p.prefix = range->addr; rn = route_node_lookup (area->ranges, (struct prefix *)&p); if (rn) { ospf_area_range_free (rn->info); rn->info = NULL; route_unlock_node (rn); route_unlock_node (rn); } }
int rip_neighbor_lookup (struct sockaddr_in *from) { struct prefix_ipv4 p; struct route_node *node; memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefix = from->sin_addr; p.prefixlen = IPV4_MAX_BITLEN; node = route_node_lookup (rip->neighbor, (struct prefix *) &p); if (node) { route_unlock_node (node); return 1; } return 0; }
struct ospf_if_params *ospf_lookup_if_params(struct interface *ifp, struct in_addr addr) { struct prefix_ipv4 p; struct route_node *rn; p.family = AF_INET; p.prefixlen = IPV4_MAX_PREFIXLEN; p.prefix = addr; rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p); if (rn) { route_unlock_node(rn); return rn->info; } return NULL; }
/* Untie an interface address from its derived subnet list of addresses. */ int if_subnet_delete (struct interface *ifp, struct connected *ifc) { struct route_node *rn; struct zebra_if *zebra_if; struct list *addr_list; assert (ifp && ifp->info && ifc); zebra_if = ifp->info; /* Get address derived subnet node. */ rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address); if (! (rn && rn->info)) return -1; route_unlock_node (rn); /* Untie address from subnet's address list. */ addr_list = rn->info; listnode_delete (addr_list, ifc); route_unlock_node (rn); /* Return list element count, if not empty. */ if (addr_list->count) { /* If deleted address is primary, mark subsequent one as such and distribute. */ if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY)) { ifc = listgetdata (listhead (addr_list)); zebra_interface_address_delete_update (ifp, ifc); UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY); zebra_interface_address_add_update (ifp, ifc); } return addr_list->count; } /* Otherwise, free list and route node. */ list_free (addr_list); rn->info = NULL; route_unlock_node (rn); return 0; }
/* Delete RIP neighbor from the neighbor tree. */ static int rip_neighbor_delete (struct prefix_ipv4 *p) { struct route_node *node; /* Lock for look up. */ node = route_node_lookup (rip->neighbor, (struct prefix *) p); if (! node) return -1; node->info = NULL; /* Unlock lookup lock. */ route_unlock_node (node); /* Unlock real neighbor information lock. */ route_unlock_node (node); return 0; }
struct ospf6_lsa * ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router, struct ospf6_lsdb *lsdb) { struct route_node *node; struct prefix_ipv6 key; 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)); node = route_node_lookup (lsdb->table, (struct prefix *) &key); if (node == NULL || node->info == NULL) return NULL; return (struct ospf6_lsa *) node->info; }
/* Delete RIPng enable network. */ static int ripng_enable_network_delete (struct prefix *p) { struct route_node *node; node = route_node_lookup (ripng_enable_network, p); if (node) { node->info = NULL; /* Unlock info lock. */ route_unlock_node (node); /* Unlock lookup lock. */ route_unlock_node (node); return 1; } return -1; }
static struct ospf_route *ospf_find_abr_route(struct route_table *rtrs, struct prefix_ipv4 *abr, struct ospf_area *area) { struct route_node *rn; struct ospf_route * or ; struct listnode *node; if ((rn = route_node_lookup(rtrs, (struct prefix *)abr)) == NULL) return NULL; route_unlock_node(rn); for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id) && (or->u.std.flags & ROUTER_LSA_BORDER)) return or ; return NULL; }
struct ospf_route * ospf_find_abr_route (struct route_table *rtrs, struct prefix_ipv4 *abr, struct ospf_area *area) { struct route_node *rn; struct ospf_route *or; listnode node; if ((rn = route_node_lookup (rtrs, (struct prefix *) abr)) == NULL) return NULL; route_unlock_node (rn); for (node = listhead ((list) rn->info); node; nextnode (node)) if ((or = getdata (node)) != NULL) if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id) && (or->u.std.flags & ROUTER_LSA_BORDER)) return or; return NULL; }
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); } }
static void ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp) { struct route_node *rn; struct prefix_ipv4 p; p.family = AF_INET; p.prefixlen = IPV4_MAX_PREFIXLEN; p.prefix = *ifaddr; rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p); if (! rn) { zlog_info ("ifaddr_ipv4_delete(): can't find address %s", inet_ntoa (*ifaddr)); return; } rn->info = NULL; route_unlock_node (rn); route_unlock_node (rn); }
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); }
/* Delete RIP enable network. */ static int rip_enable_network_delete (struct prefix *p) { struct route_node *node; node = route_node_lookup (rip_enable_network, p); if (node) { node->info = NULL; /* Unlock info lock. */ route_unlock_node (node); /* Unlock lookup lock. */ route_unlock_node (node); /* XXX: One should find a better solution than a generic one */ rip_enable_apply_all (); return 1; } return -1; }
void rip_ifaddr_delete (struct interface *ifp, struct connected *ifc) { struct prefix *p; struct route_node *rn; struct interface *i; p = ifc->address; if (p->family != AF_INET) return; rn = route_node_lookup (rip_ifaddr_table, p); if (! rn) return; i = rn->info; if (rn && !strncmp(i->name,ifp->name,INTERFACE_NAMSIZ)) { rn->info = NULL; route_unlock_node (rn); route_unlock_node (rn); } }