Commit 60dda81b authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

OSPF: Statistics

Count packet rx/tx and error conditions, per iface and globally.
Show them in 'show ospf' / 'show ospf interface'.

Also removee one level of indentation for areas in 'show ospf' command.
parent 4d3d34f5
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -218,11 +218,15 @@ ospf_send_dbdes(struct ospf_proto *p, struct ospf_neighbor *n)
void
ospf_rxmt_dbdes(struct ospf_proto *p, struct ospf_neighbor *n)
{
  struct ospf_iface *ifa = n->ifa;

  ASSERT(n->state > NEIGHBOR_EXSTART);

  if (!n->ldd_buffer)
  {
    log(L_WARN "%s: No DBDES packet for retransmit", p->p.name);
    STATS(bad_dbdes);

    ospf_neigh_sm(n, INM_SEQMIS);
    return;
  }
@@ -251,18 +255,18 @@ ospf_process_dbdes(struct ospf_proto *p, struct ospf_packet *pkt, struct ospf_ne
    /* RFC 2328 10.6 and RFC 5340 4.2.2 */

    if (!lsa_type)
      DROP1("LSA of unknown type");
      DROP1(bad_dbdes, "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");
      DROP1(bad_dbdes, "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");
      DROP1(bad_dbdes, "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");
      DROP1(bad_dbdes, "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))
@@ -311,6 +315,7 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
  if (plen < ospf_dbdes_hdrlen(p))
  {
    LOG_PKT("Bad DBDES packet from nbr %R on %s - %s (%u)", n->rid, ifa->ifname, "too short", plen);
    STATS2(bad_pkt, dropped);
    return;
  }

@@ -397,13 +402,13 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
      goto duplicate;

    if ((rcv_imms & DBDES_MS) != (n->imms & DBDES_MS))
      DROP("MS-bit mismatch", rcv_imms);
      DROP(bad_dbdes, "MS-bit mismatch", rcv_imms);

    if (rcv_imms & DBDES_I)
      DROP("I-bit mismatch", rcv_imms);
      DROP(bad_dbdes, "I-bit mismatch", rcv_imms);

    if (rcv_options != n->options)
      DROP("options mismatch", rcv_options);
      DROP(bad_dbdes, "options mismatch", rcv_options);

    n->ddr = rcv_ddseq;
    n->imms = rcv_imms;
@@ -413,7 +418,7 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
      /* MASTER */

      if (rcv_ddseq != n->dds)
	DROP("DD sequence number mismatch", rcv_ddseq);
	DROP(bad_dbdes, "DD sequence number mismatch", rcv_ddseq);

      n->dds++;

@@ -435,7 +440,7 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
      /* SLAVE */

      if (rcv_ddseq != (n->dds + 1))
	DROP("DD sequence number mismatch", rcv_ddseq);
	DROP(bad_dbdes, "DD sequence number mismatch", rcv_ddseq);

      n->ddr = rcv_ddseq;
      n->dds = rcv_ddseq;
@@ -457,7 +462,7 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
	(rcv_ddseq == n->ddr))
      goto duplicate;

    DROP("too late for DD exchange", n->state);
    DROP(bad_dbdes, "too late for DD exchange", n->state);

  default:
    bug("Undefined interface state");
+10 −10
Original line number Diff line number Diff line
@@ -206,7 +206,7 @@ ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa,
    struct ospf_hello2_packet *ps = (void *) pkt;

    if (plen < sizeof(struct ospf_hello2_packet))
      DROP("too short", plen);
      DROP(bad_pkt, "too short", plen);

    rcv_iface_id = 0;
    rcv_helloint = ntohs(ps->helloint);
@@ -218,12 +218,12 @@ ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa,

    int pxlen = u32_masklen(ntohl(ps->netmask));
    if (pxlen < 0)
      DROP("prefix garbled", ntohl(ps->netmask));
      DROP(bad_pkt, "prefix garbled", ntohl(ps->netmask));

    if ((ifa->type != OSPF_IT_VLINK) &&
	(ifa->type != OSPF_IT_PTP) &&
	((uint) pxlen != ifa->addr->prefix.pxlen))
      DROP("prefix length mismatch", pxlen);
      DROP(bad_hello, "prefix length mismatch", pxlen);

    neighbors = ps->neighbors;
    neigh_count = (plen - sizeof(struct ospf_hello2_packet)) / sizeof(u32);
@@ -233,7 +233,7 @@ ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa,
    struct ospf_hello3_packet *ps = (void *) pkt;

    if (plen < sizeof(struct ospf_hello3_packet))
      DROP("too short", plen);
      DROP(bad_pkt, "too short", plen);

    rcv_iface_id = ntohl(ps->iface_id);
    rcv_helloint = ntohs(ps->helloint);
@@ -248,18 +248,18 @@ ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa,
  }

  if (rcv_helloint != ifa->helloint)
    DROP("hello interval mismatch", rcv_helloint);
    DROP(bad_hello, "hello interval mismatch", rcv_helloint);

  if (rcv_deadint != ifa->deadint)
    DROP("dead interval mismatch", rcv_deadint);
    DROP(bad_hello, "dead interval mismatch", rcv_deadint);

  /* Check whether bits E, N match */
  if ((rcv_options ^ loc_options) & (OPT_E | OPT_N))
    DROP("area type mismatch", rcv_options);
    DROP(bad_hello, "area type mismatch", rcv_options);

  /* RFC 5838 2.4 - AF-bit check unless on IPv6 unicast */
  if ((loc_options & OPT_AF) && !(loc_options & OPT_V6) && !(rcv_options & OPT_AF))
    DROP("AF-bit mismatch", rcv_options);
    DROP(bad_hello, "AF-bit mismatch", rcv_options);

  /* Check consistency of existing neighbor entry */
  if (n)
@@ -295,12 +295,12 @@ ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa,
      struct nbma_node *nn = find_nbma_node(ifa, faddr);

      if (!nn && ifa->strictnbma)
	DROP1("new neighbor denied");
	DROP1(bad_hello, "new neighbor denied");

      if (nn && (ifa->type == OSPF_IT_NBMA) &&
	  (((rcv_priority == 0) && nn->eligible) ||
	   ((rcv_priority > 0) && !nn->eligible)))
	DROP("eligibility mismatch", rcv_priority);
	DROP(bad_hello, "eligibility mismatch", rcv_priority);

      if (nn)
	nn->found = 1;
+20 −0
Original line number Diff line number Diff line
@@ -1327,6 +1327,23 @@ ospf_if_notify(struct proto *P, uint flags, struct iface *iface)
     iface_list even when down */
}

void
ospf_iface_stats(int c, struct ospf_iface_stats *s)
{
  cli_msg(c, "\trx-hello %u rx-dbdes %u rx-lsreq %u rx-lsupd %u rx-lsack %u rx-vlink %u",
	  s->rx_pkts[0], s->rx_pkts[1], s->rx_pkts[2], s->rx_pkts[3], s->rx_pkts[4], s->rx_vlink);
  cli_msg(c, "\ttx-hello %u tx-dbdes %u tx-lsreq %u tx-lsupd %u tx-lsack %u tx-vlink %u",
	  s->tx_pkts[0], s->tx_pkts[1], s->tx_pkts[2], s->tx_pkts[3], s->tx_pkts[4], s->tx_vlink);
  cli_msg(c, "\tdropped %u bad-pkt %u bad-ver %u bad-au-type %u bad-auth %u bad-chksum %u",
	  s->dropped, s->bad_pkt, s->bad_ver, s->bad_au_type, s->bad_auth, s->bad_check);
  cli_msg(c, "\tbad-ttl %u bad-src %u bad-area %u bad-nbr %u bad-pkt-type %u bad-state %u",
	  s->bad_ttl, s->bad_src, s->bad_area, s->bad_nbr, s->bad_pkt_type, s->bad_state);
  cli_msg(c, "\tbad-hello %u bad-dbdes %u bad-lsreq %u bad-lsupd %u bad-lsack %u bad-lsa %u",
	  s->bad_hello, s->bad_dbdes, s->bad_lsreq, s->bad_lsupd, s->bad_lsack, s->bad_lsa);
  cli_msg(c, "\tsk-error %u tx-queue-full %u tx-no-key %u",
	  s->sk_error, s->tx_queue_full, s->tx_no_key);
}

void
ospf_iface_info(struct ospf_iface *ifa)
{
@@ -1379,4 +1396,7 @@ ospf_iface_info(struct ospf_iface *ifa)
    cli_msg(-1015, "\tBackup designated router (ID): %R", ifa->bdrid);
    cli_msg(-1015, "\tBackup designated router (IP): %I", ifa->bdrip);
  }

  cli_msg(-1015, "\tStatistics:");
  ospf_iface_stats(-1015, &ifa->stats);
}
+6 −1
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ ospf_receive_lsack(struct ospf_packet *pkt, struct ospf_iface *ifa,
  struct ospf_proto *p = ifa->oa->po;
  struct ospf_lsa_header lsa, *lsas;
  struct top_hash_entry *ret, *en;
  uint i, lsa_count;
  uint i, lsa_count, bad = 0;
  u32 lsa_type, lsa_domain;

  /* RFC 2328 13.7 */
@@ -145,6 +145,7 @@ ospf_receive_lsack(struct ospf_packet *pkt, struct ospf_iface *ifa,
  if (n->state < NEIGHBOR_EXCHANGE)
  {
    OSPF_TRACE(D_PACKETS, "LSACK packet ignored - lesser state than Exchange");
    STATS2(bad_state, dropped);
    return;
  }

@@ -169,6 +170,10 @@ ospf_receive_lsack(struct ospf_packet *pkt, struct ospf_iface *ifa,
		 ret->lsa.sn, ret->lsa.age, ret->lsa.checksum);
      OSPF_TRACE(D_PACKETS, "    It has: Seq: %08x, Age: %4u, Sum: %04x",
		 lsa.sn, lsa.age, lsa.checksum);

      if (!bad++)
	STATS(bad_lsack);

      continue;
    }

+2 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ ospf_receive_lsreq(struct ospf_packet *pkt, struct ospf_iface *ifa,
  if (n->state < NEIGHBOR_EXCHANGE)
  {
    OSPF_TRACE(D_PACKETS, "LSREQ packet ignored - lesser state than Exchange");
    STATS2(bad_state, dropped);
    return;
  }

@@ -134,6 +135,7 @@ ospf_receive_lsreq(struct ospf_packet *pkt, struct ospf_iface *ifa,
    {
      LOG_LSA1("Bad LSR (Type: %04x, Id: %R, Rt: %R) in LSREQ", type, id, rt);
      LOG_LSA2("  received from nbr %R on %s - LSA is missing", n->rid, ifa->ifname);
      STATS2(bad_lsreq, dropped);

      ospf_neigh_sm(n, INM_BADLSREQ);
      return;
Loading