struct ospf_if_params * ospf_get_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_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p); if (rn->info == NULL) rn->info = ospf_new_if_params (); else route_unlock_node (rn); return rn->info; }
/* Add RIPng enable network. */ static int ripng_enable_network_add (struct prefix *p) { struct route_node *node; node = route_node_get (ripng_enable_network, p); if (node->info) { route_unlock_node (node); return -1; } else node->info = (char *) "enabled"; /* XXX: One should find a better solution than a generic one */ ripng_enable_apply_all(); return 1; }
static void ifaddr_ipv4_add (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_get (ifaddr_ipv4_table, (struct prefix *) &p); if (rn) { route_unlock_node (rn); zlog_info ("ifaddr_ipv4_add(): address %s is already added", inet_ntoa (*ifaddr)); return; } rn->info = ifp; }
/* Add self to nbr list. */ void ospf_nbr_add_self(struct ospf_interface *oi, struct in_addr router_id) { struct prefix p; struct route_node *rn; if (!oi->nbr_self) oi->nbr_self = ospf_nbr_new(oi); /* Initial state */ oi->nbr_self->address = *oi->address; oi->nbr_self->priority = OSPF_IF_PARAM(oi, priority); oi->nbr_self->router_id = router_id; oi->nbr_self->src = oi->address->u.prefix4; oi->nbr_self->state = NSM_TwoWay; switch (oi->area->external_routing) { case OSPF_AREA_DEFAULT: SET_FLAG(oi->nbr_self->options, OSPF_OPTION_E); break; case OSPF_AREA_STUB: UNSET_FLAG(oi->nbr_self->options, OSPF_OPTION_E); break; case OSPF_AREA_NSSA: UNSET_FLAG(oi->nbr_self->options, OSPF_OPTION_E); SET_FLAG(oi->nbr_self->options, OSPF_OPTION_NP); break; } /* Add nbr_self to nbrs table */ ospf_nbr_key(oi, oi->nbr_self, &p); rn = route_node_get(oi->nbrs, &p); if (rn->info) { /* There is already pseudo neighbor. */ zlog_warn( "router_id %s already present in neighbor table. node refcount %u", inet_ntoa(router_id), rn->lock); route_unlock_node(rn); } else rn->info = oi->nbr_self; }
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); } }
/* Add self to nbr list. */ void ospf_nbr_add_self (struct ospf_interface *oi) { struct ospf_neighbor *nbr; struct prefix p; struct route_node *rn; p.family = AF_INET; p.prefixlen = 32; p.u.prefix4 = oi->address->u.prefix4; rn = route_node_get (oi->nbrs, &p); if (rn->info) { /* There is already pseudo neighbor. */ nbr = rn->info; route_unlock_node (rn); } else rn->info = oi->nbr_self; }
/* Add self to nbr list. */ void ospf_nbr_add_self (struct ospf_interface *oi) { struct prefix p; struct route_node *rn; /* Initial state */ oi->nbr_self->address = *oi->address; oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority); oi->nbr_self->router_id = oi->ospf->router_id; oi->nbr_self->src = oi->address->u.prefix4; oi->nbr_self->state = NSM_TwoWay; switch (oi->area->external_routing) { case OSPF_AREA_DEFAULT: SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); break; case OSPF_AREA_STUB: UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); break; case OSPF_AREA_NSSA: UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP); break; } /* Add nbr_self to nbrs table */ ospf_nbr_key (oi, oi->nbr_self, &p); rn = route_node_get (oi->nbrs, &p); if (rn->info) { /* There is already pseudo neighbor. */ assert (oi->nbr_self == rn->info); route_unlock_node (rn); } else rn->info = oi->nbr_self; }
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 ospf_neighbor * ospf_nbr_get (struct ospf_interface *oi, struct ospf_header *ospfh, struct ip *iph, struct prefix *p) { struct route_node *rn; struct prefix key; struct ospf_neighbor *nbr; key.family = AF_INET; key.prefixlen = IPV4_MAX_BITLEN; if (oi->type == OSPF_IFTYPE_VIRTUALLINK) key.u.prefix4 = ospfh->router_id; /* index vlink nbrs by router-id */ else key.u.prefix4 = iph->ip_src; rn = route_node_get (oi->nbrs, &key); if (rn->info) { route_unlock_node (rn); nbr = rn->info; if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt) { nbr->src = iph->ip_src; memcpy (&nbr->address, p, sizeof (struct prefix)); } } else { rn->info = nbr = ospf_nbr_add (oi, ospfh, p); } nbr->router_id = ospfh->router_id; return nbr; }
static void isis_redist_ensure_default(struct isis *isis, int family) { struct prefix p; struct route_table *ei_table = get_ext_info(isis, family); struct route_node *ei_node; struct isis_ext_info *info; if (family == AF_INET) { p.family = AF_INET; p.prefixlen = 0; memset(&p.u.prefix4, 0, sizeof(p.u.prefix4)); } else if (family == AF_INET6) { p.family = AF_INET6; p.prefixlen = 0; memset(&p.u.prefix6, 0, sizeof(p.u.prefix6)); } else assert(!"Unknown family!"); ei_node = route_node_get(ei_table, &p); if (ei_node->info) { route_unlock_node(ei_node); return; } ei_node->info = XCALLOC(MTYPE_ISIS, sizeof(struct isis_ext_info)); info = ei_node->info; info->origin = DEFAULT_ROUTE; info->distance = 254; info->metric = MAX_WIDE_PATH_METRIC; }
void ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix, u_int nexthop_num, struct in6_addr *nexthop) { int ret; struct ospf6_route troute; struct ospf6_external_info tinfo; struct ospf6_route *route, *match; struct ospf6_external_info *info; struct prefix prefix_id; struct route_node *node; char pbuf[64], ibuf[16]; struct listnode *lnode, *lnnode; struct ospf6_area *oa; if (! ospf6_zebra_is_redistribute (type)) return; if (IS_OSPF6_DEBUG_ASBR) { prefix2str (prefix, pbuf, sizeof (pbuf)); zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type)); } /* if route-map was specified but not found, do not advertise */ if (ospf6->rmap[type].name) { if (ospf6->rmap[type].map == NULL) ospf6_asbr_routemap_update (NULL); if (ospf6->rmap[type].map == NULL) { zlog_warn ("route-map \"%s\" not found, suppress redistributing", ospf6->rmap[type].name); return; } } /* apply route-map */ if (ospf6->rmap[type].map) { memset (&troute, 0, sizeof (troute)); memset (&tinfo, 0, sizeof (tinfo)); troute.route_option = &tinfo; ret = route_map_apply (ospf6->rmap[type].map, prefix, RMAP_OSPF6, &troute); if (ret == RMAP_DENYMATCH) { if (IS_OSPF6_DEBUG_ASBR) zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name); return; } } match = ospf6_route_lookup (prefix, ospf6->external_table); if (match) { info = match->route_option; /* copy result of route-map */ if (ospf6->rmap[type].map) { if (troute.path.metric_type) match->path.metric_type = troute.path.metric_type; if (troute.path.cost) match->path.cost = troute.path.cost; if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding)) memcpy (&info->forwarding, &tinfo.forwarding, sizeof (struct in6_addr)); } info->type = type; match->nexthop[0].ifindex = ifindex; if (nexthop_num && nexthop) memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr)); /* create/update binding in external_id_table */ prefix_id.family = AF_INET; prefix_id.prefixlen = 32; prefix_id.u.prefix4.s_addr = htonl (info->id); node = route_node_get (ospf6->external_id_table, &prefix_id); node->info = match; if (IS_OSPF6_DEBUG_ASBR) { inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf)); zlog_debug ("Advertise as AS-External Id:%s", ibuf); } match->path.origin.id = htonl (info->id); ospf6_as_external_lsa_originate (match); return; } /* create new entry */ route = ospf6_route_create (); route->type = OSPF6_DEST_TYPE_NETWORK; memcpy (&route->prefix, prefix, sizeof (struct prefix)); info = (struct ospf6_external_info *) XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info)); route->route_option = info; info->id = ospf6->external_id++; /* copy result of route-map */ if (ospf6->rmap[type].map) { if (troute.path.metric_type) route->path.metric_type = troute.path.metric_type; if (troute.path.cost) route->path.cost = troute.path.cost; if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding)) memcpy (&info->forwarding, &tinfo.forwarding, sizeof (struct in6_addr)); } info->type = type; route->nexthop[0].ifindex = ifindex; if (nexthop_num && nexthop) memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr)); /* create/update binding in external_id_table */ prefix_id.family = AF_INET; prefix_id.prefixlen = 32; prefix_id.u.prefix4.s_addr = htonl (info->id); node = route_node_get (ospf6->external_id_table, &prefix_id); node->info = route; route = ospf6_route_add (route, ospf6->external_table); route->route_option = info; if (IS_OSPF6_DEBUG_ASBR) { inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf)); zlog_debug ("Advertise as AS-External Id:%s", ibuf); } route->path.origin.id = htonl (info->id); ospf6_as_external_lsa_originate (route); /* Router-Bit (ASBR Flag) may have to be updated */ for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa)) OSPF6_ROUTER_LSA_SCHEDULE (oa); }
static void ospf_ia_router_route (struct ospf *ospf, struct route_table *rtrs, struct prefix_ipv4 *p, struct ospf_route *new_or, struct ospf_route *abr_or) { struct ospf_route *or = NULL; struct route_node *rn; int ret; if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_ia_router_route(): considering %s/%d", inet_ntoa (p->prefix), p->prefixlen); /* Find a route to the same dest */ rn = route_node_get (rtrs, (struct prefix *) p); if (rn->info == NULL) /* This is a new route */ rn->info = list_new (); else { struct ospf_area *or_area; or_area = ospf_area_lookup_by_area_id (ospf, new_or->u.std.area_id); assert (or_area); /* This is an additional route */ route_unlock_node (rn); or = ospf_find_asbr_route_through_area (rtrs, p, or_area); } if (or) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_ia_router_route(): " "a route to the same ABR through the same area exists"); /* New route is better */ if ((ret = ospf_route_cmp (ospf, new_or, or)) < 0) { listnode_delete (rn->info, or); ospf_route_free (or); /* proceed down */ } /* Routes are the same */ else if (ret == 0) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_ia_router_route(): merging the new route"); ospf_route_copy_nexthops (or, abr_or->paths); ospf_route_free (new_or); return; } /* New route is worse */ else { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_ia_router_route(): skipping the new route"); ospf_route_free (new_or); return; } } ospf_route_copy_nexthops (new_or, abr_or->paths); if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_ia_router_route(): adding the new route"); listnode_add (rn->info, new_or); }
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); }