static char * ospf6_lsdesc_backlink (struct ospf6_lsa *lsa, caddr_t lsdesc, struct ospf6_vertex *v) { caddr_t backlink, found = NULL; int size; size = (OSPF6_LSA_IS_TYPE (ROUTER, lsa) ? sizeof (struct ospf6_router_lsdesc) : sizeof (struct ospf6_network_lsdesc)); for (backlink = OSPF6_LSA_HEADER_END (lsa->header) + 4; backlink + size <= OSPF6_LSA_END (lsa->header); backlink += size) { assert (! (OSPF6_LSA_IS_TYPE (NETWORK, lsa) && VERTEX_IS_TYPE (NETWORK, v))); if (OSPF6_LSA_IS_TYPE (NETWORK, lsa) && NETWORK_LSDESC_GET_NBR_ROUTERID (backlink) == v->lsa->header->adv_router) found = backlink; else if (VERTEX_IS_TYPE (NETWORK, v) && ROUTER_LSDESC_IS_TYPE (TRANSIT_NETWORK, backlink) && ROUTER_LSDESC_GET_NBR_ROUTERID (backlink) == v->lsa->header->adv_router && ROUTER_LSDESC_GET_NBR_IFID (backlink) == ntohl (v->lsa->header->id)) found = backlink; else { if (! ROUTER_LSDESC_IS_TYPE (POINTTOPOINT, backlink) || ! ROUTER_LSDESC_IS_TYPE (POINTTOPOINT, lsdesc)) continue; if (ROUTER_LSDESC_GET_NBR_IFID (backlink) != ROUTER_LSDESC_GET_IFID (lsdesc) || ROUTER_LSDESC_GET_NBR_IFID (lsdesc) != ROUTER_LSDESC_GET_IFID (backlink)) continue; if (ROUTER_LSDESC_GET_NBR_ROUTERID (backlink) != v->lsa->header->adv_router || ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc) != lsa->header->adv_router) continue; found = backlink; } } if (IS_OSPF6_SIBLING_DEBUG_SPF) zlog_debug (" Backlink %s", (found ? "OK" : "FAIL")); return found; }
static void ospf6_nexthop_calc (struct ospf6_vertex *w, struct ospf6_vertex *v, caddr_t lsdesc) { int i; ifindex_t ifindex; struct ospf6_interface *oi; u_int16_t type; u_int32_t adv_router; struct ospf6_lsa *lsa; struct ospf6_link_lsa *link_lsa; char buf[64]; assert (VERTEX_IS_TYPE (ROUTER, w)); ifindex = (VERTEX_IS_TYPE (NETWORK, v) ? v->nexthop[0].ifindex : /* v is the local router & the interface_id is a local ifindex */ (ifindex_t) ROUTER_LSDESC_GET_IFID (lsdesc)); assert (ifindex >= 0); oi = ospf6_interface_lookup_by_ifindex (ifindex); if (oi == NULL) { if (IS_OSPF6_DEBUG_SPF (PROCESS)) zlog_debug ("Can't find interface in SPF: ifindex %d", ifindex); return; } type = htons (OSPF6_LSTYPE_LINK); adv_router = (VERTEX_IS_TYPE (NETWORK, v) ? NETWORK_LSDESC_GET_NBR_ROUTERID (lsdesc) : ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc)); i = 0; for (lsa = ospf6_lsdb_type_router_head (type, adv_router, oi->lsdb); lsa; lsa = ospf6_lsdb_type_router_next (type, adv_router, lsa)) { if (VERTEX_IS_TYPE (ROUTER, v) && htonl (ROUTER_LSDESC_GET_NBR_IFID (lsdesc)) != lsa->header->id) continue; link_lsa = (struct ospf6_link_lsa *) OSPF6_LSA_HEADER_END (lsa->header); if (IS_OSPF6_DEBUG_SPF (PROCESS)) { inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf)); zlog_debug (" nexthop %s from %s", buf, lsa->name); } if (i < OSPF6_MULTI_PATH_LIMIT) { memcpy (&w->nexthop[i].address, &link_lsa->linklocal_addr, sizeof (struct in6_addr)); w->nexthop[i].ifindex = ifindex; i++; } } if (i == 0 && IS_OSPF6_DEBUG_SPF (PROCESS)) zlog_debug ("No nexthop for %s found", w->name); }
static struct ospf6_lsa * ospf6_lsdesc_lsa(caddr_t lsdesc, struct ospf6_vertex * v) { struct ospf6_lsa *lsa; u_int16_t type = 0; u_int32_t id = 0, adv_router = 0; if (VERTEX_IS_TYPE (NETWORK, v)) { type = htons (OSPF6_LSTYPE_ROUTER); id = htonl (0); adv_router = NETWORK_LSDESC_GET_NBR_ROUTERID (lsdesc); } else { if (ROUTER_LSDESC_IS_TYPE (POINTTOPOINT, lsdesc)) { type = htons (OSPF6_LSTYPE_ROUTER); id = htonl (0); adv_router = ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc); } else if (ROUTER_LSDESC_IS_TYPE (TRANSIT_NETWORK, lsdesc)) { type = htons (OSPF6_LSTYPE_NETWORK); id = htonl (ROUTER_LSDESC_GET_NBR_IFID (lsdesc)); adv_router = ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc); } } lsa = ospf6_lsdb_lookup (type, id, adv_router, v->area->lsdb); if (IS_OSPF6_SIBLING_DEBUG_SPF) { char ibuf[16], abuf[16]; inet_ntop (AF_INET, &id, ibuf, sizeof (ibuf)); inet_ntop (AF_INET, &adv_router, abuf, sizeof (abuf)); if (lsa) zlog_debug (" Link to: %s", lsa->name); else zlog_debug (" Link to: [Id:%s Adv:%s] No LSA", // ospf6_lstype_name (type), ibuf, abuf); ibuf, abuf); } return lsa; }