static void ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct ospf_neighbor *n) { struct ospf_lsa_header *plsa, lsa; struct top_hash_entry *he, *sn; struct ospf_area *oa = n->ifa->oa; struct top_graph *gr = oa->po->gr; struct ospf_packet *op; int i, j; op = (struct ospf_packet *) ps; plsa = (void *) (ps + 1); j = (ntohs(op->length) - sizeof(struct ospf_dbdes_packet)) / sizeof(struct ospf_lsa_header); for (i = 0; i < j; i++) { ntohlsah(plsa + i, &lsa); u32 dom = ospf_lsa_domain(lsa.type, n->ifa); if (((he = ospf_hash_find_header(gr, dom, &lsa)) == NULL) || (lsa_comp(&lsa, &(he->lsa)) == 1)) { /* Is this condition necessary? */ if (ospf_hash_find_header(n->lsrqh, dom, &lsa) == NULL) { sn = ospf_hash_get_header(n->lsrqh, dom, &lsa); ntohlsah(plsa + i, &(sn->lsa)); s_add_tail(&(n->lsrql), SNODE sn); } } } }
void ospf_lsack_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, struct ospf_neighbor *n) { struct proto *p = &ifa->oa->po->proto; struct ospf_lsa_header lsa; struct top_hash_entry *en; unsigned int i, lsano; unsigned int size = ntohs(ps_i->length); if (size < sizeof(struct ospf_lsack_packet)) { log(L_ERR "Bad OSPF LSACK packet from %I - too short (%u B)", n->ip, size); return; } struct ospf_lsack_packet *ps = (void *) ps_i; OSPF_PACKET(ospf_dump_lsack, ps, "LSACK packet received from %I via %s", n->ip, ifa->iface->name); ospf_neigh_sm(n, INM_HELLOREC); if (n->state < NEIGHBOR_EXCHANGE) return; lsano = (size - sizeof(struct ospf_lsack_packet)) / sizeof(struct ospf_lsa_header); for (i = 0; i < lsano; i++) { ntohlsah(ps->lsh + i, &lsa); u32 dom = ospf_lsa_domain(lsa.type, n->ifa); if ((en = ospf_hash_find_header(n->lsrth, dom, &lsa)) == NULL) continue; /* pg 155 */ if (lsa_comp(&lsa, &en->lsa) != CMP_SAME) /* pg 156 */ { if ((lsa.sn == LSA_MAXSEQNO) && (lsa.age == LSA_MAXAGE)) continue; OSPF_TRACE(D_PACKETS, "Strange LSACK from %I", n->ip); OSPF_TRACE(D_PACKETS, "Type: %04x, Id: %R, Rt: %R", lsa.type, lsa.id, lsa.rt); OSPF_TRACE(D_PACKETS, "I have: Age: %4u, Seq: %08x, Sum: %04x", en->lsa.age, en->lsa.sn, en->lsa.checksum); OSPF_TRACE(D_PACKETS, "He has: Age: %4u, Seq: %08x, Sum: %04x", lsa.age, lsa.sn, lsa.checksum); continue; } DBG("Deleting LS Id: %R RT: %R Type: %u from LS Retl for neighbor %R\n", lsa.id, lsa.rt, lsa.type, n->rid); s_rem_node(SNODE en); if (en->lsa_body != NULL) mb_free(en->lsa_body); en->lsa_body = NULL; ospf_hash_delete(n->lsrth, en); } }
static int ospf_process_dbdes(struct ospf_proto *p, struct ospf_packet *pkt, struct ospf_neighbor *n) { struct ospf_iface *ifa = n->ifa; struct ospf_lsa_header *lsas, lsa; struct top_hash_entry *en, *req; const char *err_dsc = NULL; u32 lsa_type, lsa_domain; uint i, lsa_count; ospf_dbdes_body(p, pkt, &lsas, &lsa_count); for (i = 0; i < lsa_count; i++) { lsa_ntoh_hdr(lsas + i, &lsa); lsa_get_type_domain(&lsa, ifa, &lsa_type, &lsa_domain); /* RFC 2328 10.6 and RFC 5340 4.2.2 */ if (!lsa_type) DROP1("LSA of unknown type"); if (!oa_is_ext(ifa->oa) && (LSA_SCOPE(lsa_type) == LSA_SCOPE_AS)) DROP1("LSA with AS scope in stub area"); /* Errata 3746 to RFC 2328 - rt-summary-LSAs forbidden in stub areas */ if (!oa_is_ext(ifa->oa) && (lsa_type == LSA_T_SUM_RT)) DROP1("rt-summary-LSA in stub area"); /* Not explicitly mentioned in RFC 5340 4.2.2 but makes sense */ if (LSA_SCOPE(lsa_type) == LSA_SCOPE_RES) DROP1("LSA with invalid scope"); en = ospf_hash_find(p->gr, lsa_domain, lsa.id, lsa.rt, lsa_type); if (!en || (lsa_comp(&lsa, &(en->lsa)) == CMP_NEWER)) { /* This should be splitted to ospf_lsa_lsrq_up() */ req = ospf_hash_get(n->lsrqh, lsa_domain, lsa.id, lsa.rt, lsa_type); if (!SNODE_VALID(req)) s_add_tail(&n->lsrql, SNODE req); if (!SNODE_VALID(n->lsrqi)) n->lsrqi = req; req->lsa = lsa; req->lsa_body = LSA_BODY_DUMMY; if (!tm_active(n->lsrq_timer)) tm_start(n->lsrq_timer, 0); } } return 0; drop: LOG_LSA1("Bad LSA (Type: %04x, Id: %R, Rt: %R) in DBDES", lsa_type, lsa.id, lsa.rt); LOG_LSA2(" received from nbr %R on %s - %s", n->rid, ifa->ifname, err_dsc); ospf_neigh_sm(n, INM_SEQMIS); return -1; }