summaryrefslogtreecommitdiff
path: root/proto/ospf/lsupd.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2014-10-24 10:27:21 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2014-10-24 11:07:38 +0200
commitf8fefde318c6248ad94e7b6d60155deed9ab8eed (patch)
tree4edd3eb9b152f016afc2482555fb62b04f96eeb2 /proto/ospf/lsupd.c
parent78342404ff573e85e396f0611014b90cea9b4c0a (diff)
Refactoring of OSPF messages.
Diffstat (limited to 'proto/ospf/lsupd.c')
-rw-r--r--proto/ospf/lsupd.c96
1 files changed, 43 insertions, 53 deletions
diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c
index 13ae54d1..0aa45f6a 100644
--- a/proto/ospf/lsupd.c
+++ b/proto/ospf/lsupd.c
@@ -338,7 +338,7 @@ ospf_send_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa
{ i++; continue; }
OSPF_PACKET(ospf_dump_lsupd, ospf_tx_buffer(ifa),
- "LSUPD packet sent to %I via %s", n->ip, ifa->ifname);
+ "LSUPD packet sent to nbr %R on %s", n->rid, ifa->ifname);
ospf_send_to(ifa, n->ip);
}
@@ -396,24 +396,22 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
struct ospf_neighbor *n)
{
struct ospf_proto *p = ifa->oa->po;
-
- /* RFC 2328 13. */
-
+ const char *err_dsc = NULL;
+ uint plen, err_val = 0;
int skip_lsreq = 0;
n->want_lsreq = 0;
- uint plen = ntohs(pkt->length);
+ /* RFC 2328 13. */
+
+ plen = ntohs(pkt->length);
if (plen < (ospf_lsupd_hdrlen(p) + sizeof(struct ospf_lsa_header)))
- {
- log(L_ERR "OSPF: Bad LSUPD packet from %I - too short (%u B)", n->ip, plen);
- return;
- }
+ DROP("too short", plen);
- OSPF_PACKET(ospf_dump_lsupd, pkt, "LSUPD packet received from %I via %s", n->ip, ifa->ifname);
+ OSPF_PACKET(ospf_dump_lsupd, pkt, "LSUPD packet received from nbr %R on %s", n->rid, ifa->ifname);
if (n->state < NEIGHBOR_EXCHANGE)
{
- OSPF_TRACE(D_PACKETS, "Received lsupd in lesser state than EXCHANGE from (%I)", n->ip);
+ OSPF_TRACE(D_PACKETS, "LSUPD packet ignored - lesser state than Exchange");
return;
}
@@ -429,33 +427,18 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
u32 lsa_len, lsa_type, lsa_domain;
if (offset > bound)
- {
- log(L_WARN "%s: Received LSUPD from %I is too short", p->p.name, n->ip);
- ospf_neigh_sm(n, INM_BADLSREQ);
- return;
- }
+ DROP("too short", plen);
/* LSA header in network order */
lsa_n = ((void *) pkt) + offset;
lsa_len = ntohs(lsa_n->length);
offset += lsa_len;
- if ((offset > plen) || ((lsa_len % 4) != 0) ||
- (lsa_len <= sizeof(struct ospf_lsa_header)))
- {
- log(L_WARN "%s: Received LSA from %I with bad length", p->p.name, n->ip);
- ospf_neigh_sm(n, INM_BADLSREQ);
- return;
- }
+ if (offset > plen)
+ DROP("too short", plen);
- /* RFC 2328 13. (1) - validate LSA checksum */
- u16 chsum = lsa_n->checksum;
- if (chsum != lsasum_check(lsa_n, NULL))
- {
- log(L_WARN "%s: Received LSA from %I with bad checksum: %x %x",
- p->p.name, n->ip, chsum, lsa_n->checksum);
- continue;
- }
+ if (((lsa_len % 4) != 0) || (lsa_len <= sizeof(struct ospf_lsa_header)))
+ DROP("invalid LSA length", lsa_len);
/* LSA header in host order */
lsa_ntoh_hdr(lsa_n, &lsa);
@@ -464,33 +447,25 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
DBG("Update Type: %04x, Id: %R, Rt: %R, Sn: 0x%08x, Age: %u, Sum: %u\n",
lsa_type, lsa.id, lsa.rt, lsa.sn, lsa.age, lsa.checksum);
+ /* RFC 2328 13. (1) - validate LSA checksum */
+ if (lsa_n->checksum != lsasum_check(lsa_n, NULL))
+ SKIP("invalid checksum");
+
/* RFC 2328 13. (2) */
if (!lsa_type)
- {
- log(L_WARN "%s: Received unknown LSA type from %I", p->p.name, n->ip);
- continue;
- }
+ SKIP("unknown type");
/* RFC 5340 4.5.1 (2) and RFC 2328 13. (3) */
if (!oa_is_ext(ifa->oa) && (LSA_SCOPE(lsa_type) == LSA_SCOPE_AS))
- {
- log(L_WARN "%s: Received LSA with AS scope in stub area from %I", p->p.name, n->ip);
- continue;
- }
+ SKIP("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))
- {
- log(L_WARN "%s: Received rt-summary-LSA in stub area from %I", p->p.name, n->ip);
- continue;
- }
+ SKIP("rt-summary-LSA in stub area");
/* RFC 5340 4.5.1 (3) */
if (LSA_SCOPE(lsa_type) == LSA_SCOPE_RES)
- {
- log(L_WARN "%s: Received LSA with invalid scope from %I", p->p.name, n->ip);
- continue;
- }
+ SKIP("invalid scope");
/* Find local copy of LSA in link state database */
en = ospf_hash_find(p->gr, lsa_domain, lsa.id, lsa.rt, lsa_type);
@@ -528,9 +503,8 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
if (lsa_validate(&lsa, lsa_type, ospf_is_v2(p), body) == 0)
{
- log(L_WARN "%s: Received invalid LSA from %I", p->p.name, n->ip);
mb_free(body);
- continue;
+ SKIP("invalid body");
}
/* 13. (5f) - handle self-originated LSAs, see also 13.4. */
@@ -542,8 +516,8 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
continue;
}
- /* 13. (5c) - remove old LSA from all retransmission lists */
- /*
+ /* 13. (5c) - remove old LSA from all retransmission lists
+ *
* We only need to remove it from the retransmission list of the neighbor
* that send us the new LSA. The old LSA is automatically replaced in
* retransmission lists by the new LSA.
@@ -561,8 +535,8 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
WALK_LIST(ifi, p->iface_list)
WALK_LIST(ni, ifi->neigh_list)
- if (ni->state > NEIGHBOR_EXSTART)
- ospf_lsa_lsrt_down(en, ni);
+ if (ni->state > NEIGHBOR_EXSTART)
+ ospf_lsa_lsrt_down(en, ni);
#endif
/* 13. (5d) - install new LSA into database */
@@ -615,7 +589,13 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
/* Send newer local copy back to neighbor */
/* FIXME - check for MinLSArrival ? */
ospf_send_lsupd(p, &en, 1, n);
+
+ continue;
}
+
+ skip:
+ LOG_LSA1("Bad LSA (Type: %04x, Id: %R, Rt: %R) in LSUPD", lsa_type, lsa.id, lsa.rt);
+ LOG_LSA2(" received from nbr %R on %s - %s", n->rid, ifa->ifname, err_dsc);
}
/* Send direct LSACKs */
@@ -630,4 +610,14 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
*/
if ((n->state == NEIGHBOR_LOADING) && n->want_lsreq && !skip_lsreq)
ospf_send_lsreq(p, n);
+
+ return;
+
+drop:
+ LOG_PKT("Bad LSUPD packet from nbr %R on %s - %s (%u)",
+ n->rid, ifa->ifname, err_dsc, err_val);
+
+ // XXXX realy?
+ ospf_neigh_sm(n, INM_SEQMIS);
+ return;
}