summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_lsa.c
diff options
context:
space:
mode:
authorhasso <hasso>2004-05-18 18:57:06 +0000
committerhasso <hasso>2004-05-18 18:57:06 +0000
commit508e53e2eef3eefba4c1aa771529027fd4486ea8 (patch)
tree0e25e1b344a7b8e2c4551cfcb74d5a011dd0865d /ospf6d/ospf6_lsa.c
parent6708fa3c3e6aef369be13f3915698f407107cae2 (diff)
Ospf6d merge from Zebra repository with added privs stuff and merged
zclient changes.
Diffstat (limited to 'ospf6d/ospf6_lsa.c')
-rw-r--r--ospf6d/ospf6_lsa.c1867
1 files changed, 446 insertions, 1421 deletions
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index 712aa686..13e9a073 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -1,6 +1,5 @@
/*
- * LSA function
- * Copyright (C) 1999 Yasuhiro Ohara
+ * Copyright (C) 2003 Yasuhiro Ohara
*
* This file is part of GNU Zebra.
*
@@ -23,73 +22,56 @@
#include <zebra.h>
/* Include other stuffs */
-#include <lib/version.h>
#include "log.h"
-#include "getopt.h"
#include "linklist.h"
-#include "thread.h"
#include "command.h"
#include "memory.h"
-#include "sockunion.h"
-#include "if.h"
-#include "prefix.h"
-#include "stream.h"
#include "thread.h"
-#include "filter.h"
-#include "zclient.h"
-#include "table.h"
-#include "plist.h"
+#include "ospf6d.h"
#include "ospf6_proto.h"
-#include "ospf6_prefix.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
#include "ospf6_message.h"
-#include "ospf6_dump.h"
#include "ospf6_top.h"
#include "ospf6_area.h"
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"
-#include "ospf6_ism.h"
-#include "ospf6_nsm.h"
-#include "ospf6_dbex.h"
-#define HEADER_DEPENDENCY
-#include "ospf6d.h"
-#undef HEADER_DEPENDENCY
+#include "ospf6_flood.h"
-/* test LSAs identity */
-static int
-ospf6_lsa_issame (struct ospf6_lsa_header__ *lsh1,
- struct ospf6_lsa_header__ *lsh2)
-{
- assert (lsh1 && lsh2);
+unsigned char conf_debug_ospf6_lsa = 0;
- if (lsh1->adv_router != lsh2->adv_router)
- return 0;
+struct ospf6_lstype ospf6_lstype[OSPF6_LSTYPE_SIZE];
- if (lsh1->id != lsh2->id)
- return 0;
+char *ospf6_lstype_str[OSPF6_LSTYPE_SIZE] =
+ {"Unknown", "Router", "Network", "Inter-Prefix", "Inter-Router",
+ "AS-External", "Group-Membership", "Type-7", "Link", "Intra-Prefix"};
- if (lsh1->type != lsh2->type)
- return 0;
+char *
+ospf6_lstype_name (u_int16_t type)
+{
+ static char buf[8];
+ int index = ntohs (type) & OSPF6_LSTYPE_FCODE_MASK;
+
+ if (index < OSPF6_LSTYPE_SIZE && ospf6_lstype_str[index])
+ return ospf6_lstype_str[index];
- return 1;
+ snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type));
+ return buf;
}
/* RFC2328: Section 13.2 */
int
-ospf6_lsa_differ (struct ospf6_lsa *lsa1,
- struct ospf6_lsa *lsa2)
+ospf6_lsa_is_differ (struct ospf6_lsa *lsa1,
+ struct ospf6_lsa *lsa2)
{
- int diff, cmplen;
+ int len;
- if (! ospf6_lsa_issame (lsa1->header, lsa2->header))
- return 1;
+ assert (OSPF6_LSA_IS_SAME (lsa1, lsa2));
- /* check Options field */
- /* xxx */
+ /* XXX, Options ??? */
ospf6_lsa_age_current (lsa1);
ospf6_lsa_age_current (lsa2);
@@ -104,26 +86,26 @@ ospf6_lsa_differ (struct ospf6_lsa *lsa1,
if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
return 1;
- cmplen = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header);
- diff = memcmp (lsa1->header + 1, lsa2->header + 1, cmplen);
-
- return diff;
+ len = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header);
+ return memcmp (lsa1->header + 1, lsa2->header + 1, len);
}
int
-ospf6_lsa_match (u_int16_t type, u_int32_t id, u_int32_t adv_router,
- struct ospf6_lsa_header *lsh)
+ospf6_lsa_is_changed (struct ospf6_lsa *lsa1,
+ struct ospf6_lsa *lsa2)
{
- if (lsh->advrtr != adv_router)
- return 0;
+ int length;
- if (lsh->ls_id != id)
- return 0;
+ if (OSPF6_LSA_IS_MAXAGE (lsa1) ^ OSPF6_LSA_IS_MAXAGE (lsa2))
+ return 1;
+ if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
+ return 1;
- if (lsh->type != type)
- return 0;
+ length = OSPF6_LSA_SIZE (lsa1->header) - sizeof (struct ospf6_lsa_header);
+ assert (length > 0);
- return 1;
+ return memcmp (OSPF6_LSA_HEADER_END (lsa1->header),
+ OSPF6_LSA_HEADER_END (lsa2->header), length);
}
/* ospf6 age functions */
@@ -143,7 +125,8 @@ ospf6_lsa_age_set (struct ospf6_lsa *lsa)
lsa->birth.tv_usec = now.tv_usec;
if (ntohs (lsa->header->age) != MAXAGE)
lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
- lsa->birth.tv_sec + MAXAGE - now.tv_sec);
+ MAXAGE + lsa->birth.tv_sec
+ - now.tv_sec);
else
lsa->expire = NULL;
return;
@@ -163,17 +146,14 @@ ospf6_lsa_age_current (struct ospf6_lsa *lsa)
/* current time */
if (gettimeofday (&now, (struct timezone *)NULL) < 0)
- zlog_warn ("LSA: gettimeofday failed, may fail ages: %s",
+ zlog_warn ("LSA: gettimeofday failed, may fail LSA AGEs: %s",
strerror (errno));
/* calculate age */
ulage = now.tv_sec - lsa->birth.tv_sec;
/* if over MAXAGE, set to it */
- if (ulage > MAXAGE)
- age = MAXAGE;
- else
- age = ulage;
+ age = (ulage > MAXAGE ? MAXAGE : ulage);
lsa->header->age = htons (age);
return age;
@@ -189,22 +169,17 @@ ospf6_lsa_age_update_to_send (struct ospf6_lsa *lsa, u_int32_t transdelay)
if (age > MAXAGE)
age = MAXAGE;
lsa->header->age = htons (age);
- return;
}
void
ospf6_lsa_premature_aging (struct ospf6_lsa *lsa)
{
/* log */
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: Premature aging: %s", lsa->str);
+ if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+ zlog_info ("LSA: Premature aging: %s", lsa->name);
- if (lsa->expire)
- thread_cancel (lsa->expire);
- lsa->expire = (struct thread *) NULL;
- if (lsa->refresh)
- thread_cancel (lsa->refresh);
- lsa->refresh = (struct thread *) NULL;
+ THREAD_OFF (lsa->expire);
+ THREAD_OFF (lsa->refresh);
memset (&lsa->birth, 0, sizeof (struct timeval));
thread_execute (master, ospf6_lsa_expire, lsa, 0);
@@ -213,7 +188,7 @@ ospf6_lsa_premature_aging (struct ospf6_lsa *lsa)
/* check which is more recent. if a is more recent, return -1;
if the same, return 0; otherwise(b is more recent), return 1 */
int
-ospf6_lsa_check_recent (struct ospf6_lsa *a, struct ospf6_lsa *b)
+ospf6_lsa_compare (struct ospf6_lsa *a, struct ospf6_lsa *b)
{
signed long seqnuma, seqnumb;
u_int16_t cksuma, cksumb;
@@ -221,7 +196,7 @@ ospf6_lsa_check_recent (struct ospf6_lsa *a, struct ospf6_lsa *b)
assert (a && a->header);
assert (b && b->header);
- assert (ospf6_lsa_issame (a->header, b->header));
+ assert (OSPF6_LSA_IS_SAME (a, b));
seqnuma = ((signed long) ntohl (a->header->seqnum))
- (signed long) INITIAL_SEQUENCE_NUMBER;
@@ -229,8 +204,7 @@ ospf6_lsa_check_recent (struct ospf6_lsa *a, struct ospf6_lsa *b)
- (signed long) INITIAL_SEQUENCE_NUMBER;
/* compare by sequence number */
- /* xxx, care about LS sequence number wrapping */
- recent_reason = "seqnum";
+ /* XXX, LS sequence number wrapping */
if (seqnuma > seqnumb)
return -1;
else if (seqnuma < seqnumb)
@@ -244,188 +218,89 @@ ospf6_lsa_check_recent (struct ospf6_lsa *a, struct ospf6_lsa *b)
if (cksuma < cksumb)
return 0;
- /* Age check */
+ /* Update Age */
agea = ospf6_lsa_age_current (a);
ageb = ospf6_lsa_age_current (b);
- /* MaxAge check */
- recent_reason = "max age";
- if (agea == OSPF6_LSA_MAXAGE && ageb != OSPF6_LSA_MAXAGE)
+ /* MaxAge check */
+ if (agea == MAXAGE && ageb != MAXAGE)
return -1;
- else if (agea != OSPF6_LSA_MAXAGE && ageb == OSPF6_LSA_MAXAGE)
+ else if (agea != MAXAGE && ageb == MAXAGE)
return 1;
- recent_reason = "age differ";
- if (agea > ageb && agea - ageb >= OSPF6_LSA_MAXAGEDIFF)
+ /* Age check */
+ if (agea > ageb && agea - ageb >= MAX_AGE_DIFF)
return 1;
- else if (agea < ageb && ageb - agea >= OSPF6_LSA_MAXAGEDIFF)
+ else if (agea < ageb && ageb - agea >= MAX_AGE_DIFF)
return -1;
/* neither recent */
- recent_reason = "the same instance";
return 0;
}
-int
-ospf6_lsa_lsd_num (struct ospf6_lsa_header *lsa_header)
-{
- int ldnum = 0;
- u_int16_t len;
-
- len = ntohs (lsa_header->length);
- len -= sizeof (struct ospf6_lsa_header);
- if (lsa_header->type == htons (OSPF6_LSA_TYPE_ROUTER))
- {
- len -= sizeof (struct ospf6_router_lsa);
- ldnum = len / sizeof (struct ospf6_router_lsd);
- }
- else /* (lsa_header->type == htons (OSPF6_LSA_TYPE_NETWORK)) */
- {
- len -= sizeof (struct ospf6_network_lsa);
- ldnum = len / sizeof (u_int32_t);
- }
-
- return ldnum;
-}
-
-void *
-ospf6_lsa_lsd_get (int index, struct ospf6_lsa_header *lsa_header)
-{
- void *p;
- struct ospf6_router_lsa *router_lsa;
- struct ospf6_router_lsd *router_lsd;
- struct ospf6_network_lsa *network_lsa;
- struct ospf6_network_lsd *network_lsd;
-
- if (lsa_header->type == htons (OSPF6_LSA_TYPE_ROUTER))
- {
- router_lsa = (struct ospf6_router_lsa *) (lsa_header + 1);
- router_lsd = (struct ospf6_router_lsd *) (router_lsa + 1);
- router_lsd += index;
- p = (void *) router_lsd;
- }
- else if (lsa_header->type == htons (OSPF6_LSA_TYPE_NETWORK))
- {
- network_lsa = (struct ospf6_network_lsa *) (lsa_header + 1);
- network_lsd = (struct ospf6_network_lsd *) (network_lsa + 1);
- network_lsd += index;
- p = (void *) network_lsd;
- }
- else
- {
- p = (void *) NULL;
- }
-
- return p;
-}
-
-/* network_lsd <-> router_lsd */
-static int
-ospf6_lsa_lsd_network_reference_match (struct ospf6_network_lsd *network_lsd1,
- struct ospf6_lsa_header *lsa_header1,
- struct ospf6_router_lsd *router_lsd2,
- struct ospf6_lsa_header *lsa_header2)
+char *
+ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size)
{
- if (network_lsd1->adv_router != lsa_header2->advrtr)
- return 0;
- if (router_lsd2->type != OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK)
- return 0;
- if (router_lsd2->neighbor_router_id != lsa_header1->advrtr)
- return 0;
- if (router_lsd2->neighbor_interface_id != lsa_header1->ls_id)
- return 0;
- return 1;
+ char id[16], adv_router[16];
+ inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
+ inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
+ sizeof (adv_router));
+ snprintf (buf, size, "[%s Id:%s Adv:%s]",
+ OSPF6_LSTYPE_NAME (lsa->header->type), id, adv_router);
+ return buf;
}
-/* router_lsd <-> router_lsd */
-static int
-ospf6_lsa_lsd_router_reference_match (struct ospf6_router_lsd *router_lsd1,
- struct ospf6_lsa_header *lsa_header1,
- struct ospf6_router_lsd *router_lsd2,
- struct ospf6_lsa_header *lsa_header2)
+void
+ospf6_lsa_header_print_raw (struct ospf6_lsa_header *header)
{
- if (router_lsd1->type != OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT)
- return 0;
- if (router_lsd2->type != OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT)
- return 0;
- if (router_lsd1->neighbor_router_id != lsa_header2->advrtr)
- return 0;
- if (router_lsd2->neighbor_router_id != lsa_header1->advrtr)
- return 0;
- if (router_lsd1->neighbor_interface_id != router_lsd2->interface_id)
- return 0;
- if (router_lsd2->neighbor_interface_id != router_lsd1->interface_id)
- return 0;
- return 1;
+ char id[16], adv_router[16];
+ inet_ntop (AF_INET, &header->id, id, sizeof (id));
+ inet_ntop (AF_INET, &header->adv_router, adv_router,
+ sizeof (adv_router));
+ zlog_info (" [%s Id:%s Adv:%s]",
+ OSPF6_LSTYPE_NAME (header->type), id, adv_router);
+ zlog_info (" Age: %4hu SeqNum: %#08lx Cksum: %04hx Len: %d",
+ ntohs (header->age), (u_long) ntohl (header->seqnum),
+ ntohs (header->checksum), ntohs (header->length));
}
-int
-ospf6_lsa_lsd_is_refer_ok (int index1, struct ospf6_lsa_header *lsa_header1,
- int index2, struct ospf6_lsa_header *lsa_header2)
+void
+ospf6_lsa_header_print (struct ospf6_lsa *lsa)
{
- struct ospf6_router_lsd *r1, *r2;
- struct ospf6_network_lsd *n;
-
- r1 = (struct ospf6_router_lsd *) NULL;
- r2 = (struct ospf6_router_lsd *) NULL;
- n = (struct ospf6_network_lsd *) NULL;
- if (lsa_header1->type == htons (OSPF6_LSA_TYPE_ROUTER))
- r1 = (struct ospf6_router_lsd *) ospf6_lsa_lsd_get (index1, lsa_header1);
- else
- n = (struct ospf6_network_lsd *) ospf6_lsa_lsd_get (index1, lsa_header1);
-
- if (lsa_header2->type == htons (OSPF6_LSA_TYPE_ROUTER))
- r2 = (struct ospf6_router_lsd *) ospf6_lsa_lsd_get (index2, lsa_header2);
- else
- n = (struct ospf6_network_lsd *) ospf6_lsa_lsd_get (index2, lsa_header2);
-
- if (r1 && r2)
- return ospf6_lsa_lsd_router_reference_match (r1, lsa_header1,
- r2, lsa_header2);
- else if (r1 && n)
- return ospf6_lsa_lsd_network_reference_match (n, lsa_header2,
- r1, lsa_header1);
- else if (n && r2)
- return ospf6_lsa_lsd_network_reference_match (n, lsa_header1,
- r2, lsa_header2);
- return 0;
+ ospf6_lsa_age_current (lsa);
+ ospf6_lsa_header_print_raw (lsa->header);
}
void
ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
- char adv_router[64], id[64], type[32];
+ char adv_router[64], id[64];
+ int index;
- assert (lsa);
- assert (lsa->header);
+ assert (lsa && lsa->header);
- ospf6_lsa_type_string (lsa->header->type, type, sizeof (type));
inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
inet_ntop (AF_INET, &lsa->header->adv_router,
adv_router, sizeof (adv_router));
vty_out (vty, "%s", VTY_NEWLINE);
vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
- type, VTY_NEWLINE);
+ OSPF6_LSTYPE_NAME (lsa->header->type), VTY_NEWLINE);
vty_out (vty, "Link State ID: %s%s", id, VTY_NEWLINE);
vty_out (vty, "Advertising Router: %s%s", adv_router, VTY_NEWLINE);
- vty_out (vty, "LS Sequence Number: %#lx%s", (u_long)ntohl (lsa->header->seqnum),
- VTY_NEWLINE);
- vty_out (vty, "CheckSum: %#hx Length: %hu%s", ntohs (lsa->header->checksum),
+ vty_out (vty, "LS Sequence Number: %#010lx%s",
+ (u_long) ntohl (lsa->header->seqnum), VTY_NEWLINE);
+ vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
+ ntohs (lsa->header->checksum),
ntohs (lsa->header->length), VTY_NEWLINE);
- {
- struct ospf6_lsa_slot *slot;
- slot = ospf6_lsa_slot_get (lsa->header->type);
- if (slot)
- {
- (*slot->func_show) (vty, lsa);
- vty_out (vty, "%s", VTY_NEWLINE);
- return;
- }
- }
-
- vty_out (vty, "%sUnknown LSA type ...%s", VTY_NEWLINE, VTY_NEWLINE);
+ index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
+ if (ospf6_lstype[index].show)
+ (*ospf6_lstype[index].show) (vty, lsa);
+ else
+ vty_out (vty, "%sUnknown LSA type ...%s", VTY_NEWLINE, VTY_NEWLINE);
+
+ vty_out (vty, "%s", VTY_NEWLINE);
}
void
@@ -439,25 +314,24 @@ ospf6_lsa_show_summary_header (struct vty *vty)
void
ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa)
{
- char adv_router[16], id[16], type[16];
+ char adv_router[16], id[16];
struct timeval now, res;
char duration[16];
assert (lsa);
assert (lsa->header);
- memset (type, 0, sizeof (type));
- ospf6_lsa_type_string (lsa->header->type, type, 13);
inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
sizeof (adv_router));
gettimeofday (&now, NULL);
- ospf6_timeval_sub (&now, &lsa->installed, &res);
- ospf6_timeval_string_summary (&res, duration, sizeof (duration));
+ timersub (&now, &lsa->installed, &res);
+ timerstring (&res, duration, sizeof (duration));
vty_out (vty, "%-12s %-15s %-15s %4hu %8lx %04hx %4hu %8s%s",
- type, id, adv_router, ospf6_lsa_age_current (lsa),
+ OSPF6_LSTYPE_NAME (lsa->header->type),
+ id, adv_router, ospf6_lsa_age_current (lsa),
(u_long) ntohl (lsa->header->seqnum),
ntohs (lsa->header->checksum), ntohs (lsa->header->length),
duration, VTY_NEWLINE);
@@ -473,7 +347,7 @@ ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
end = (char *) lsa->header + ntohs (lsa->header->length);
vty_out (vty, "%s", VTY_NEWLINE);
- vty_out (vty, "%s:%s", lsa->str, VTY_NEWLINE);
+ vty_out (vty, "%s:%s", lsa->name, VTY_NEWLINE);
for (current = start; current < end; current ++)
{
@@ -489,149 +363,136 @@ ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
vty_out (vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE);
}
+void
+ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa)
+{
+ char adv_router[64], id[64];
+
+ assert (lsa && lsa->header);
+
+ inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
+ inet_ntop (AF_INET, &lsa->header->adv_router,
+ adv_router, sizeof (adv_router));
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
+ OSPF6_LSTYPE_NAME (lsa->header->type), VTY_NEWLINE);
+ vty_out (vty, "Link State ID: %s%s", id, VTY_NEWLINE);
+ vty_out (vty, "Advertising Router: %s%s", adv_router, VTY_NEWLINE);
+ vty_out (vty, "LS Sequence Number: %#010lx%s",
+ (u_long) ntohl (lsa->header->seqnum), VTY_NEWLINE);
+ vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
+ ntohs (lsa->header->checksum),
+ ntohs (lsa->header->length), VTY_NEWLINE);
+ vty_out (vty, " Prev: %p This: %p Next: %p%s",
+ lsa->prev, lsa, lsa->next, VTY_NEWLINE);
+ vty_out (vty, " Reference count: %ld%s", lsa->refcnt, VTY_NEWLINE);
+ vty_out (vty, " Reference source: %s (%p) %s",
+ (lsa->refsrc ? lsa->refsrc->name : "None"),
+ lsa->refsrc, VTY_NEWLINE);
+ vty_out (vty, "%s", VTY_NEWLINE);
+}
+
/* OSPFv3 LSA creation/deletion function */
/* calculate LS sequence number for my new LSA.
return value is network byte order */
-static signed long
-ospf6_lsa_seqnum_new (u_int16_t type, u_int32_t id, u_int32_t adv_router,
+u_int32_t
+ospf6_lsa_new_seqnum (u_int16_t type, u_int32_t id, u_int32_t adv_router,
void *scope)
{
+ struct ospf6_lsdb *lsdb = NULL;
struct ospf6_lsa *lsa;
- signed long seqnum;
+ signed long seqnum = 0;
/* get current database copy */
- lsa = ospf6_lsdb_lookup (type, id, adv_router, scope);
+ lsdb = ospf6_get_scoped_lsdb (type, scope);
+ if (lsdb == NULL)
+ {
+ zlog_warn ("Can't decide scoped LSDB");
+ return ((u_int32_t) htonl (INITIAL_SEQUENCE_NUMBER));
+ }
/* if current database copy not found, return InitialSequenceNumber */
- if (!lsa)
+ lsa = ospf6_lsdb_lookup (type, id, adv_router, lsdb);
+ if (lsa == NULL)
seqnum = INITIAL_SEQUENCE_NUMBER;
else
seqnum = (signed long) ntohl (lsa->header->seqnum) + 1;
- return (htonl (seqnum));
-}
-
-#if 0
-static void
-ospf6_lsa_header_set (u_int16_t type, u_int32_t ls_id, u_int32_t advrtr,
- struct ospf6_lsa_header *lsa_header, int bodysize)
-{
- /* fill LSA header */
- lsa_header->age = 0;
- lsa_header->type = type;
- lsa_header->ls_id = ls_id;
- lsa_header->advrtr = advrtr;
- lsa_header->seqnum =
- ospf6_lsa_seqnum_new (lsa_header->type, lsa_header->ls_id,
- lsa_header->advrtr);
- lsa_header->length = htons (sizeof (struct ospf6_lsa_header) + bodysize);
-
- /* LSA checksum */
- ospf6_lsa_checksum (lsa_header);
+ return ((u_int32_t) htonl (seqnum));
}
-#endif /*0*/
struct ospf6_lsa *
-ospf6_lsa_create (struct ospf6_lsa_header *source)
+ospf6_lsa_create (struct ospf6_lsa_header *header)
{
struct ospf6_lsa *lsa = NULL;
- struct ospf6_lsa_header *lsa_header = NULL;
+ struct ospf6_lsa_header *new_header = NULL;
u_int16_t lsa_size = 0;
- char buf_router[16], buf_id[16], typebuf[32];
- /* whole length of this LSA */
- lsa_size = ntohs (source->length);
+ /* size of the entire LSA */
+ lsa_size = ntohs (header->length); /* XXX vulnerable */
/* allocate memory for this LSA */
- lsa_header = (struct ospf6_lsa_header *)
+ new_header = (struct ospf6_lsa_header *)
XMALLOC (MTYPE_OSPF6_LSA, lsa_size);
- if (! lsa_header)
- {
- zlog_err ("Can't allocate memory for LSA Header");
- return (struct ospf6_lsa *) NULL;
- }
- memset (lsa_header, 0, lsa_size);
- /* copy LSA from source */
- memcpy (lsa_header, source, lsa_size);
+ /* copy LSA from original header */
+ memcpy (new_header, header, lsa_size);
/* LSA information structure */
/* allocate memory */
lsa = (struct ospf6_lsa *)
- XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
+ XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
memset (lsa, 0, sizeof (struct ospf6_lsa));
- lsa->lsa_hdr = (struct ospf6_lsa_hdr *) lsa_header;
- lsa->header = (struct ospf6_lsa_header__ *) lsa_header;
-
- lsa->summary = 0; /* this is not LSA summary */
+ lsa->header = (struct ospf6_lsa_header *) new_header;
+ lsa->headeronly = 0; /* this is not header only */
/* dump string */
- inet_ntop (AF_INET, &lsa->header->id, buf_id, sizeof (buf_id));
- inet_ntop (AF_INET, &lsa->header->adv_router, buf_router,
- sizeof (buf_router));
- snprintf (lsa->str, sizeof (lsa->str), "[%s ID=%s Adv=%s]",
- ospf6_lsa_type_string (lsa_header->type, typebuf,
- sizeof (typebuf)),
- buf_id, buf_router);
+ ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
/* calculate birth, expire and refresh of this lsa */
ospf6_lsa_age_set (lsa);
-#ifdef DEBUG
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Create: %s (%p/%p)", lsa->str, lsa, lsa->header);
-#endif /*DEBUG*/
+ if (IS_OSPF6_DEBUG_LSA (MEMORY))
+ zlog_info ("Create LSA Memory: %s (%p/%p)",
+ lsa->name, lsa, lsa->header);
return lsa;
}
struct ospf6_lsa *
-ospf6_lsa_summary_create (struct ospf6_lsa_header__ *source)
+ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header)
{
struct ospf6_lsa *lsa = NULL;
- struct ospf6_lsa_header *lsa_header = NULL;
- u_int16_t lsa_size = 0;
- char buf_router[16], buf_id[16], typebuf[16];
-
- /* LSA summary contains LSA Header only */
- lsa_size = sizeof (struct ospf6_lsa_header);
+ struct ospf6_lsa_header *new_header = NULL;
/* allocate memory for this LSA */
- lsa_header = (struct ospf6_lsa_header *)
- XMALLOC (MTYPE_OSPF6_LSA_SUMMARY, lsa_size);
- memset (lsa_header, 0, lsa_size);
+ new_header = (struct ospf6_lsa_header *)
+ XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_header));
- /* copy LSA from source */
- memcpy (lsa_header, source, lsa_size);
+ /* copy LSA from original header */
+ memcpy (new_header, header, sizeof (struct ospf6_lsa_header));
/* LSA information structure */
/* allocate memory */
lsa = (struct ospf6_lsa *)
- XMALLOC (MTYPE_OSPF6_LSA_SUMMARY, sizeof (struct ospf6_lsa));
+ XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
memset (lsa, 0, sizeof (struct ospf6_lsa));
- lsa->lsa_hdr = (struct ospf6_lsa_hdr *) lsa_header;
- lsa->header = (struct ospf6_lsa_header__ *) lsa_header;
- lsa->summary = 1; /* this is LSA summary */
+ lsa->header = (struct ospf6_lsa_header *) new_header;
+ lsa->headeronly = 1; /* this is header only */
/* dump string */
- inet_ntop (AF_INET, &lsa->header->id, buf_id, sizeof (buf_id));
- inet_ntop (AF_INET, &lsa->header->adv_router, buf_router,
- sizeof (buf_router));
- snprintf (lsa->str, sizeof (lsa->str), "[%s Summary ID=%s Adv=%s]",
- ospf6_lsa_type_string (lsa->header->type, typebuf,
- sizeof (typebuf)),
- buf_id, buf_router);
+ ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
/* calculate birth, expire and refresh of this lsa */
ospf6_lsa_age_set (lsa);
-#ifdef DEBUG
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Create: %s (%p/%p)", lsa->str, lsa, lsa->header);
-#endif /*DEBUG*/
+ if (IS_OSPF6_DEBUG_LSA (MEMORY))
+ zlog_info ("Create LSA (Header-only) Memory: %s (%p/%p)",
+ lsa->name, lsa, lsa->header);
return lsa;
}
@@ -639,40 +500,48 @@ ospf6_lsa_summary_create (struct ospf6_lsa_header__ *source)
void
ospf6_lsa_delete (struct ospf6_lsa *lsa)
{
- /* just to make sure */
- if (lsa->lock != 0)
- {
- zlog_err ("Can't delete %s: lock: %ld", lsa->str, lsa->lock);
- return;
- }
+ assert (lsa->lock == 0);
/* cancel threads */
- if (lsa->expire)
- thread_cancel (lsa->expire);
- lsa->expire = (struct thread *) NULL;
- if (lsa->refresh)
- thread_cancel (lsa->refresh);
- lsa->refresh = (struct thread *) NULL;
+ THREAD_OFF (lsa->expire);
+ THREAD_OFF (lsa->refresh);
-#ifdef DEBUG
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Delete %s (%p/%p)", lsa->str, lsa, lsa->header);
-#endif /*DEBUG*/
+ if (IS_OSPF6_DEBUG_LSA (MEMORY))
+ zlog_info ("Delete LSA %s Memory: %s (%p/%p)",
+ (lsa->headeronly ? "(Header-only) " : ""),
+ lsa->name, lsa, lsa->header);
/* do free */
- if (lsa->summary)
- XFREE (MTYPE_OSPF6_LSA_SUMMARY, lsa->header);
- else
- XFREE (MTYPE_OSPF6_LSA, lsa->header);
- lsa->header = NULL;
+ XFREE (MTYPE_OSPF6_LSA, lsa->header);
+ XFREE (MTYPE_OSPF6_LSA, lsa);
+}
- if (lsa->summary)
- XFREE (MTYPE_OSPF6_LSA_SUMMARY, lsa);
+struct ospf6_lsa *
+ospf6_lsa_copy (struct ospf6_lsa *lsa)
+{
+ struct ospf6_lsa *copy = NULL;
+
+ if (IS_OSPF6_DEBUG_LSA (MEMORY))
+ zlog_info ("Create LSA Copy from %s", lsa->name);
+
+ ospf6_lsa_age_current (lsa);
+ if (lsa->headeronly)
+ copy = ospf6_lsa_create_headeronly (lsa->header);
else
- XFREE (MTYPE_OSPF6_LSA, lsa);
+ copy = ospf6_lsa_create (lsa->header);
+ assert (copy->lock == 0);
+
+ copy->installed = lsa->installed;
+ copy->originated = lsa->originated;
+ copy->scope = lsa->scope;
+
+ copy->refsrc = lsa;
+ copy->refsrc->refcnt++;
+
+ return copy;
}
-/* increment reference counter of struct ospf6_lsa */
+/* increment reference counter of struct ospf6_lsa */
void
ospf6_lsa_lock (struct ospf6_lsa *lsa)
{
@@ -680,163 +549,156 @@ ospf6_lsa_lock (struct ospf6_lsa *lsa)
return;
}
-/* decrement reference counter of struct ospf6_lsa */
+/* decrement reference counter of struct ospf6_lsa */
void
ospf6_lsa_unlock (struct ospf6_lsa *lsa)
{
/* decrement reference counter */
- if (lsa->lock > 0)
- lsa->lock--;
- else
- zlog_warn ("Can't unlock %s: already no lock", lsa->str);
+ assert (lsa->lock > 0);
+ lsa->lock--;
- if (lsa->lock == 0)
- ospf6_lsa_delete (lsa);
+ if (lsa->lock != 0)
+ return;
+
+ if (lsa->refsrc)
+ lsa->refsrc->refcnt--;
+
+ ospf6_lsa_delete (lsa);
}
void
-ospf6_lsa_originate (u_int16_t type, u_int32_t id, u_int32_t adv_router,
- char *data, int data_len, void *scope)
+ospf6_lsa_originate (struct ospf6_lsa *lsa)
{
- char buffer[MAXLSASIZE];
- struct ospf6_lsa_header *lsa_header;
- struct ospf6_lsa *lsa;
struct ospf6_lsa *old;
-
- assert (data_len <= sizeof (buffer) - sizeof (struct ospf6_lsa_header));
-
- lsa_header = (struct ospf6_lsa_header *) buffer;
-
- /* Copy LSA Body */
- memcpy (buffer + sizeof (struct ospf6_lsa_header), data, data_len);
-
- /* Fill LSA Header */
- lsa_header->age = 0;
- lsa_header->type = type;
- lsa_header->ls_id = id;
- lsa_header->advrtr = adv_router;
- lsa_header->seqnum =
- ospf6_lsa_seqnum_new (lsa_header->type, lsa_header->ls_id,
- lsa_header->advrtr, scope);
- lsa_header->length = htons (sizeof (struct ospf6_lsa_header) + data_len);
-
- /* LSA checksum */
- ospf6_lsa_checksum (lsa_header);
-
- /* create LSA */
- lsa = ospf6_lsa_create ((struct ospf6_lsa_header *) buffer);
- lsa->scope = scope;
+ struct ospf6_lsdb *lsdb = NULL;
/* find previous LSA */
+ lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
+ if (lsdb == NULL)
+ {
+ zlog_warn ("Can't decide scoped LSDB");
+ ospf6_lsa_delete (lsa);
+ return;
+ }
+
old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
- lsa->header->adv_router, lsa->scope);
+ lsa->header->adv_router, lsdb);
if (old)
{
- /* Check if this is neither different instance nor refresh, return */
- if (! CHECK_FLAG (old->flag, OSPF6_LSA_FLAG_REFRESH) &&
- ! ospf6_lsa_differ (lsa, old))
+ /* If this origination is neither different instance nor refresh,
+ suppress this origination */
+ if (! CHECK_FLAG (old->flag, OSPF6_LSA_REFRESH) &&
+ ! OSPF6_LSA_IS_DIFFER (lsa, old))
{
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: Suppress updating %s", lsa->str);
+ if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+ zlog_info ("Suppress updating LSA: %s", lsa->name);
ospf6_lsa_delete (lsa);
return;
}
}
lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
- OSPF6_LS_REFRESH_TIME);
- gettimeofday (&lsa->originated, NULL);
-
- //if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: originate %s seq: %#x age: %hu %ld.%06ld",
- lsa->str, ntohl (lsa->header->seqnum),
- ospf6_lsa_age_current (lsa),
- lsa->originated.tv_sec, lsa->originated.tv_usec);
-
- ospf6_dbex_remove_from_all_retrans_list (lsa);
- ospf6_dbex_flood (lsa, NULL);
- ospf6_lsdb_install (lsa);
+ LS_REFRESH_TIME);
+
+ if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+ {
+ zlog_info ("LSA Originate:");
+ ospf6_lsa_header_print (lsa);
+ }
+
+ if (old)
+ ospf6_flood_clear (old);
+ ospf6_flood_lsa (lsa, NULL);
+ ospf6_install_lsa (lsa, lsdb);
+}
+
+void
+ospf6_lsa_re_originate (struct ospf6_lsa *lsa)
+{
+ u_int16_t index;
+
+ if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+ {
+ zlog_info ("LSA Reoriginate:");
+ ospf6_lsa_header_print (lsa);
+ }
+
+ index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
+ if (ospf6_lstype[index].reoriginate)
+ (*ospf6_lstype[index].reoriginate) (lsa);
+ else
+ ospf6_lsa_premature_aging (lsa);
}
-/* ospf6_lsa expired */
+/* ospf6 lsa expiry */
int
ospf6_lsa_expire (struct thread *thread)
{
struct ospf6_lsa *lsa;
struct ospf6_lsdb *lsdb = NULL;
- void (*hook) (struct ospf6_lsa *, struct ospf6_lsa *);
lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
- assert (lsa && lsa->lsa_hdr);
- /* assertion */
- assert (IS_LSA_MAXAGE (lsa));
- assert (!lsa->refresh);
+ assert (lsa && lsa->header);
+ assert (OSPF6_LSA_IS_MAXAGE (lsa));
+ assert (! lsa->refresh);
lsa->expire = (struct thread *) NULL;
- /* log */
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: Expire: %s", lsa->str);
-
- if (!lsa->summary)
+ if (IS_OSPF6_DEBUG_LSA (TIMER))
{
- /* reflood lsa */
- ospf6_dbex_flood (lsa, NULL);
-
- /* get scoped lsdb, call remove hook */
- if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (lsa->header->type)))
- lsdb = ((struct ospf6_interface *) lsa->scope)->lsdb;
- else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (lsa->header->type)))
- lsdb = ((struct ospf6_area *) lsa->scope)->lsdb;
- else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (lsa->header->type)))
- lsdb = ((struct ospf6 *) lsa->scope)->lsdb;
- else
- assert (0);
+ zlog_info ("LSA Expire:");
+ ospf6_lsa_header_print (lsa);
+ }
- /* call LSDB hook to re-process LSA */
- hook = ospf6_lsdb_hook[ntohs (lsa->header->type) &
- OSPF6_LSTYPE_CODE_MASK].hook;
- if (hook)
- (*hook) (NULL, lsa);
+ if (lsa->headeronly)
+ return 0; /* dbexchange will do something ... */
- /* do not free LSA, and do nothing about lslists.
- wait event (ospf6_lsdb_check_maxage) */
+ /* reflood lsa */
+ ospf6_flood_lsa (lsa, NULL);
+
+ /* reinstall lsa */
+ lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
+ if (lsdb == NULL)
+ {
+ zlog_warn ("Can't decide scoped LSDB: %s", lsa->name);
+ return 0;
}
+ if (IS_OSPF6_DEBUG_LSA (DATABASE))
+ zlog_info ("Reinstall MaxAge %s", lsa->name);
+ ospf6_lsdb_add (lsa, lsdb);
+
+ /* schedule maxage remover */
+ ospf6_maxage_remove (ospf6);
return 0;
}
+/* Below will become dummy thread.
+ refresh function must be set individually per each LSAs */
int
ospf6_lsa_refresh (struct thread *thread)
{
struct ospf6_lsa *lsa;
- struct ospf6_lsa_slot *slot;
assert (thread);
- lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
- assert (lsa && lsa->lsa_hdr);
+ lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
+ assert (lsa && lsa->header);
- /* this will be used later as flag to decide really originate */
lsa->refresh = (struct thread *) NULL;
- SET_FLAG (lsa->flag, OSPF6_LSA_FLAG_REFRESH);
- /* log */
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA Refresh: %s", lsa->str);
+ /* this will be used later to decide really originate or not */
+ SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
- slot = ospf6_lsa_slot_get (lsa->header->type);
- if (slot)
+ if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
{
- zlog_info ("LSA Refresh: %s", slot->name);
- (*slot->func_refresh) (lsa);
- return 0;
+ zlog_info ("LSA Refresh:");
+ ospf6_lsa_header_print (lsa);
}
- zlog_warn ("Can't Refresh LSA: Unknown type: %#x",
- ntohs (lsa->header->type));
- return 1;
+ ospf6_lsa_re_originate (lsa);
+ return 0;
}
@@ -885,1042 +747,205 @@ ospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header)
}
int
-ospf6_lsa_is_known_type (struct ospf6_lsa_header *lsa_header)
+ospf6_unknown_reoriginate (struct ospf6_lsa *lsa)
{
- struct ospf6_lsa_slot *slot;
-
- slot = ospf6_lsa_slot_get (lsa_header->type);
- if (slot)
- return 1;
+ ospf6_lsa_premature_aging (lsa);
return 0;
}
-struct ospf6_lsa_slot *slot_head = NULL;
-
-struct ospf6_lsa_slot *
-ospf6_lsa_slot_get (u_int16_t type)
-{
- struct ospf6_lsa_slot *slot;
-
- for (slot = slot_head; slot; slot = slot->next)
- {
- if (slot->type == type)
- return slot;
- }
-
- return NULL;
-}
-
int
-ospf6_lsa_slot_register (struct ospf6_lsa_slot *src)
+ospf6_unknown_show (struct vty *vty, struct ospf6_lsa *lsa)
{
- struct ospf6_lsa_slot *new, *slot;
-
- slot = ospf6_lsa_slot_get (src->type);
- if (slot)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: Slot register: already exists: %#x %s",
- slot->type, slot->name);
- return -1;
- }
-
- new = (struct ospf6_lsa_slot *)
- XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_slot));
- if (! new)
- {
- zlog_err ("Can't allocate memory for LSA slot: %s", strerror (errno));
- return -1;
- }
- memset (new, 0, sizeof (struct ospf6_lsa_slot));
- memcpy (new, src, sizeof (struct ospf6_lsa_slot));
+ u_char *start, *end, *current;
+ char byte[4];
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: Slot register: %#x %s", slot->type, slot->name);
+ start = (char *) lsa->header + sizeof (struct ospf6_lsa_header);
+ end = (char *) lsa->header + ntohs (lsa->header->length);
- if (slot_head == NULL)
+ vty_out (vty, " Unknown contents:%s", VTY_NEWLINE);
+ for (current = start; current < end; current ++)
{
- new->prev = NULL;
- new->next = NULL;
- slot_head = new;
- return 0;
- }
-
- slot = slot_head;
- while (slot->next)
- slot = slot->next;
-
- slot->next = new;
- new->prev = slot;
-
- return 0;
-}
-
-int
-ospf6_lsa_slot_unregister (u_int16_t type)
-{
- struct ospf6_lsa_slot *slot;
+ if ((current - start) % 16 == 0)
+ vty_out (vty, "%s ", VTY_NEWLINE);
+ else if ((current - start) % 4 == 0)
+ vty_out (vty, " ");
- slot = ospf6_lsa_slot_get (type);
- if (slot == NULL)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Registering LSA slot: no such slot: %#x", type);
- return -1;
+ snprintf (byte, sizeof (byte), "%02x", *current);
+ vty_out (vty, "%s", byte);
}
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Unregistering LSA Slot: %#x %s", slot->type, slot->name);
-
- if (slot->prev)
- slot->prev->next = slot->next;
- if (slot->next)
- slot->next->prev = slot->prev;
-
- if (slot_head == slot)
- slot_head = slot->next;
-
- XFREE (MTYPE_OSPF6_LSA, slot);
+ vty_out (vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE);
return 0;
}
-char *
-ospf6_lsa_type_string (u_int16_t type, char *buf, int bufsize)
+void
+ospf6_lsa_init ()
{
- struct ospf6_lsa_slot *slot;
+ memset (ospf6_lstype, 0, sizeof (ospf6_lstype));
- slot = ospf6_lsa_slot_get (type);
- if (slot)
- snprintf (buf, bufsize, "%s", slot->name);
- else
- snprintf (buf, bufsize, "Type=0x%04x", ntohs (type));
-
- return buf;
+ ospf6_lstype[0].name = "Unknown";
+ ospf6_lstype[0].reoriginate = ospf6_unknown_reoriginate;
+ ospf6_lstype[0].show = ospf6_unknown_show;
}
-/*******************/
-/* LSA Origination */
-/*******************/
-
-#define CONTINUE_IF_ADDRESS_LINKLOCAL(addr)\
- if (IN6_IS_ADDR_LINKLOCAL (&(addr)->u.prefix6))\
- {\
- char buf[64];\
- prefix2str (addr, buf, sizeof (buf));\
- if (IS_OSPF6_DUMP_LSA)\
- zlog_info (" Filter out Linklocal: %s", buf);\
- continue;\
- }
-
-#define CONTINUE_IF_ADDRESS_UNSPECIFIED(addr)\
- if (IN6_IS_ADDR_UNSPECIFIED (&(addr)->u.prefix6))\
- {\
- char buf[64];\
- prefix2str (addr, buf, sizeof (buf));\
- if (IS_OSPF6_DUMP_LSA)\
- zlog_info (" Filter out Unspecified: %s", buf);\
- continue;\
- }
-
-#define CONTINUE_IF_ADDRESS_LOOPBACK(addr)\
- if (IN6_IS_ADDR_LOOPBACK (&(addr)->u.prefix6))\
- {\
- char buf[64];\
- prefix2str (addr, buf, sizeof (buf));\
- if (IS_OSPF6_DUMP_LSA)\
- zlog_info (" Filter out Loopback: %s", buf);\
- continue;\
- }
-
-#define CONTINUE_IF_ADDRESS_V4COMPAT(addr)\
- if (IN6_IS_ADDR_V4COMPAT (&(addr)->u.prefix6))\
- {\
- char buf[64];\
- prefix2str (addr, buf, sizeof (buf));\
- if (IS_OSPF6_DUMP_LSA)\
- zlog_info (" Filter out V4Compat: %s", buf);\
- continue;\
- }
-
-#define CONTINUE_IF_ADDRESS_V4MAPPED(addr)\
- if (IN6_IS_ADDR_V4MAPPED (&(addr)->u.prefix6))\
- {\
- char buf[64];\
- prefix2str (addr, buf, sizeof (buf));\
- if (IS_OSPF6_DUMP_LSA)\
- zlog_info (" Filter out V4Mapped: %s", buf);\
- continue;\
- }
-
-/******************************/
-/* RFC2740 3.4.3.1 Router-LSA */
-/******************************/
-
-char *
-ospf6_lsa_router_bits_string (u_char router_bits, char *buf, int size)
-{
- char w, v, e, b;
-
- w = (router_bits & OSPF6_ROUTER_LSA_BIT_W ? 'W' : '-');
- v = (router_bits & OSPF6_ROUTER_LSA_BIT_V ? 'V' : '-');
- e = (router_bits & OSPF6_ROUTER_LSA_BIT_E ? 'E' : '-');
- b = (router_bits & OSPF6_ROUTER_LSA_BIT_B ? 'B' : '-');
- snprintf (buf, size, "----%c%c%c%c", w, v, e, b);
- return buf;
-}
-
-int
-ospf6_lsa_router_show (struct vty *vty, struct ospf6_lsa *lsa)
-{
- char *start, *end, *current;
- char buf[32], name[32], bits[32], options[32];
- struct ospf6_router_lsa *router_lsa;
- struct ospf6_router_lsd *lsdesc;
-
- assert (lsa->header);
-
- router_lsa = (struct ospf6_router_lsa *)
- ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
-
- ospf6_lsa_router_bits_string (router_lsa->bits, bits, sizeof (bits));
- ospf6_options_string (router_lsa->options, options, sizeof (options));
- vty_out (vty, " Bits: %s Options: %s%s", bits, options, VTY_NEWLINE);
-
- start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
- end = (char *) lsa->header + ntohs (lsa->header->length);
- for (current = start; current + sizeof (struct ospf6_router_lsd) <= end;
- current += sizeof (struct ospf6_router_lsd))
- {
- lsdesc = (struct ospf6_router_lsd *) current;
-
- if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT)
- snprintf (name, sizeof (name), "Point-To-Point");
- else if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK)
- snprintf (name, sizeof (name), "Transit-Network");
- else if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_STUB_NETWORK)
- snprintf (name, sizeof (name), "Stub-Network");
- else if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_VIRTUAL_LINK)
- snprintf (name, sizeof (name), "Virtual-Link");
- else
- snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
-
- vty_out (vty, " Type: %s Metric: %d%s",
- name, ntohs (lsdesc->metric), VTY_NEWLINE);
- vty_out (vty, " Interface ID: %s%s",
- inet_ntop (AF_INET, &lsdesc->interface_id,
- buf, sizeof (buf)), VTY_NEWLINE);
- vty_out (vty, " Neighbor Interface ID: %s%s",
- inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
- buf, sizeof (buf)), VTY_NEWLINE);
- vty_out (vty, " Neighbor Router ID: %s%s",
- inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
- buf, sizeof (buf)), VTY_NEWLINE);
- }
- return 0;
-}
-
-u_long
-ospf6_lsa_has_elasped (u_int16_t type, u_int32_t id,
- u_int32_t adv_router, void *scope)
-{
- struct ospf6_lsa *old;
- struct timeval now;
- if (adv_router != ospf6->router_id)
- zlog_info ("LSA: Router-ID changed ?");
-
- old = ospf6_lsdb_lookup (type, id, adv_router, scope);
- if (! old)
- return OSPF6_LSA_MAXAGE;
-
- gettimeofday (&now, NULL);
- return ((u_long) SEC_TVDIFF (&now, &old->originated));
-}
-
-int
-ospf6_lsa_originate_router (struct thread *thread)
-{
- char buffer [MAXLSASIZE];
- u_int16_t size;
- struct ospf6_area *o6a;
- int count;
- u_int32_t area_id;
-
- struct ospf6_router_lsa *router_lsa;
- struct ospf6_router_lsd *router_lsd;
- listnode i;
- struct ospf6_interface *o6i;
- struct ospf6_neighbor *o6n = NULL;
-
- area_id = (u_int32_t) THREAD_ARG (thread);
-
- o6a = ospf6_area_lookup (area_id, ospf6);
- if (! o6a)
- {
- inet_ntop (AF_INET, &area_id, buffer, sizeof (buffer));
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: Update Router-LSA: No such area: %s", buffer);
- return 0;
+DEFUN (debug_ospf6_lsa_sendrecv,
+ debug_ospf6_lsa_sendrecv_cmd,
+ "debug ospf6 lsa (send|recv|originate|timer|database|memory|all)",
+ DEBUG_STR
+ OSPF6_STR
+ "Debug Link State Advertisements (LSAs)\n"
+ "Debug Sending LSAs\n"
+ "Debug Receiving LSAs\n"
+ "Debug Originating LSAs\n"
+ "Debug Timer Event of LSAs\n"
+ "Debug LSA Database\n"
+ "Debug Memory of LSAs\n"
+ "Debug LSAs all\n"
+ )
+{
+ unsigned char level = 0;
+
+ if (argc)
+ {
+ if (! strncmp (argv[0], "s", 1))
+ level = OSPF6_DEBUG_LSA_SEND;
+ else if (! strncmp (argv[0], "r", 1))
+ level = OSPF6_DEBUG_LSA_RECV;
+ else if (! strncmp (argv[0], "o", 1))
+ level = OSPF6_DEBUG_LSA_ORIGINATE;
+ else if (! strncmp (argv[0], "t", 1))
+ level = OSPF6_DEBUG_LSA_TIMER;
+ else if (! strncmp (argv[0], "d", 1))
+ level = OSPF6_DEBUG_LSA_DATABASE;
+ else if (! strncmp (argv[0], "m", 1))
+ level = OSPF6_DEBUG_LSA_MEMORY;
+ else if (! strncmp (argv[0], "a", 1))
+ {
+ level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
+ OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER |
+ OSPF6_DEBUG_LSA_DATABASE | OSPF6_DEBUG_LSA_MEMORY;
+ }
}
-
- /* clear thread */
- o6a->thread_router_lsa = NULL;
-
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: originate Router-LSA for Area %s", o6a->str);
-
- size = sizeof (struct ospf6_router_lsa);
- memset (buffer, 0, sizeof (buffer));
- router_lsa = (struct ospf6_router_lsa *) buffer;
-
- OSPF6_OPT_CLEAR_ALL (router_lsa->options);
- OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
- OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
- OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
- OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
- OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
- OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
-
- OSPF6_ROUTER_LSA_CLEAR_ALL_BITS (router_lsa);
- OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_B);
-
- if (ospf6_is_asbr (o6a->ospf6))
- OSPF6_ROUTER_LSA_SET (router_lsa, OSPF6_ROUTER_LSA_BIT_E);
else
- OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_E);
-
- OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_V);
- OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_W);
-
- /* describe links for each interfaces */
- router_lsd = (struct ospf6_router_lsd *) (router_lsa + 1);
- for (i = listhead (o6a->if_list); i; nextnode (i))
{
- o6i = (struct ospf6_interface *) getdata (i);
- assert (o6i);
-
- /* Interfaces in state Down or Loopback are not described */
- if (o6i->state == IFS_DOWN || o6i->state == IFS_LOOPBACK)
- continue;
-
- /* Nor are interfaces without any full adjacencies described */
- count = 0;
- o6i->foreach_nei (o6i, &count, NBS_FULL, ospf6_count_state);
- if (count == 0)
- continue;
-
- /* Point-to-Point interfaces */
- if (if_is_pointopoint (o6i->interface))
+ level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
+ OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER;
+ }
+
+ OSPF6_DEBUG_LSA_ON (level);
+ return CMD_SUCCESS;
+}
+
+ALIAS (debug_ospf6_lsa_sendrecv,
+ debug_ospf6_lsa_cmd,
+ "debug ospf6 lsa",
+ NO_STR
+ DEBUG_STR
+ OSPF6_STR
+ "Debug Link State Advertisements (LSAs)\n"
+ );
+
+DEFUN (no_debug_ospf6_lsa_sendrecv,
+ no_debug_ospf6_lsa_sendrecv_cmd,
+ "no debug ospf6 lsa (send|recv|originate|timer|database|memory|all)",
+ NO_STR
+ DEBUG_STR
+ OSPF6_STR
+ "Debug Link State Advertisements (LSAs)\n"
+ "Debug Sending LSAs\n"
+ "Debug Receiving LSAs\n"
+ "Debug Originating LSAs\n"
+ "Debug Timer Event of LSAs\n"
+ "Debug LSA Database\n"
+ "Debug Memory of LSAs\n"
+ "Debug LSAs all\n"
+ )
+{
+ unsigned char level = 0;
+
+ if (argc)
+ {
+ if (! strncmp (argv[0], "s", 1))
+ level = OSPF6_DEBUG_LSA_SEND;
+ else if (! strncmp (argv[0], "r", 1))
+ level = OSPF6_DEBUG_LSA_RECV;
+ else if (! strncmp (argv[0], "o", 1))
+ level = OSPF6_DEBUG_LSA_ORIGINATE;
+ else if (! strncmp (argv[0], "t", 1))
+ level = OSPF6_DEBUG_LSA_TIMER;
+ else if (! strncmp (argv[0], "d", 1))
+ level = OSPF6_DEBUG_LSA_DATABASE;
+ else if (! strncmp (argv[0], "m", 1))
+ level = OSPF6_DEBUG_LSA_MEMORY;
+ else if (! strncmp (argv[0], "a", 1))
{
- if (listcount (o6i->neighbor_list) == 0)
- continue;
-
- if (listcount (o6i->neighbor_list) != 1)
- zlog_warn ("LSA: Multiple neighbors on PoinToPoint: %s",
- o6i->interface->name);
-
- o6n = (struct ospf6_neighbor *)
- getdata (listhead (o6i->neighbor_list));
- assert (o6n);
-
- router_lsd->type = OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT;
- router_lsd->metric = htons (o6i->cost);
- router_lsd->interface_id = htonl (o6i->if_id);
- router_lsd->neighbor_interface_id = htonl (o6n->ifid);
- router_lsd->neighbor_router_id = o6n->router_id;
-
- size += sizeof (struct ospf6_router_lsd);
- router_lsd ++;
-
- continue;
+ level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
+ OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER |
+ OSPF6_DEBUG_LSA_DATABASE | OSPF6_DEBUG_LSA_MEMORY;
}
-
- /* Broadcast and NBMA interfaces */
- if (if_is_broadcast (o6i->interface))
- {
- /* If this router is not DR,
- and If this router not fully adjacent with DR,
- this interface is not transit yet: ignore. */
- if (o6i->state != IFS_DR)
- {
- o6n = ospf6_neighbor_lookup (o6i->dr, o6i); /* find DR */
- if (o6n == NULL || o6n->state != NBS_FULL)
- continue;
- }
- else
- {
- count = 0;
- o6i->foreach_nei (o6i, &count, NBS_FULL, ospf6_count_state);
- if (count == 0)
- continue;
- }
-
- router_lsd->type = OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK;
- router_lsd->metric = htons (o6i->cost);
- router_lsd->interface_id = htonl (o6i->if_id);
- if (o6i->state != IFS_DR)
- {
- router_lsd->neighbor_interface_id = htonl (o6n->ifid);
- router_lsd->neighbor_router_id = o6n->router_id;
- }
- else
- {
- router_lsd->neighbor_interface_id = htonl (o6i->if_id);
- router_lsd->neighbor_router_id = o6i->area->ospf6->router_id;
- }
-
- size += sizeof (struct ospf6_router_lsd);
- router_lsd ++;
-
- continue;
- }
-
- /* Virtual links */
- /* xxx */
- /* Point-to-Multipoint interfaces */
- /* xxx */
}
-
- ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_ROUTER),
- htonl (0), o6a->ospf6->router_id,
- (char *) router_lsa, size, o6a);
- return 0;
-}
-
-void
-ospf6_lsa_schedule_router (struct ospf6_area *area)
-{
- u_long elasped_time, time = 0;
-
- if (area->thread_router_lsa)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: schedule: Router-LSA for Area %s: another thread",
- area->str);
- return;
- }
-
- elasped_time =
- ospf6_lsa_has_elasped (htons (OSPF6_LSA_TYPE_ROUTER), htonl (0),
- area->ospf6->router_id, area);
- if (elasped_time < OSPF6_MIN_LS_INTERVAL)
- time = (u_long) (OSPF6_MIN_LS_INTERVAL - elasped_time);
- else
- time = 0;
-
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("LSA: schedule: Router-LSA for Area %s after %lu sec",
- area->str, time);
-
- if (time)
- area->thread_router_lsa =
- thread_add_timer (master, ospf6_lsa_originate_router,
- (void *) area->area_id, time);
else
- area->thread_router_lsa =
- thread_add_event (master, ospf6_lsa_originate_router,
- (void *) area->area_id, 0);
-}
-
-int
-ospf6_lsa_router_hook_neighbor (void *neighbor)
-{
- struct ospf6_neighbor *o6n = neighbor;
- if (o6n->ospf6_interface->area)
- ospf6_lsa_schedule_router (o6n->ospf6_interface->area);
- return 0;
-}
-
-int
-ospf6_lsa_router_hook_interface (void *interface)
-{
- struct ospf6_interface *o6i = interface;
- if (o6i->area)
- ospf6_lsa_schedule_router (o6i->area);
- return 0;
-}
-
-int
-ospf6_lsa_router_hook_area (void *area)
-{
- struct ospf6_area *o6a = area;
- ospf6_lsa_schedule_router (o6a);
- return 0;
-}
-
-int
-ospf6_lsa_router_hook_top (void *ospf6)
-{
- struct ospf6 *o6 = ospf6;
- struct ospf6_area *o6a;
- listnode node;
-
- for (node = listhead (o6->area_list); node; nextnode (node))
{
- o6a = getdata (node);
- ospf6_lsa_schedule_router (o6a);
+ level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
+ OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER;
}
- return 0;
-}
-
-int
-ospf6_lsa_router_refresh (void *old)
-{
- struct ospf6_lsa *lsa = old;
- struct ospf6_area *o6a;
-
- o6a = lsa->scope;
- ospf6_lsa_schedule_router (o6a);
- return 0;
-}
-
-void
-ospf6_lsa_slot_register_router ()
-{
- struct ospf6_lsa_slot slot;
- struct ospf6_hook hook;
-
- memset (&slot, 0, sizeof (struct ospf6_lsa_slot));
- slot.type = htons (OSPF6_LSA_TYPE_ROUTER);
- slot.name = "Router";
- slot.func_show = ospf6_lsa_router_show;
- slot.func_refresh = ospf6_lsa_router_refresh;
- ospf6_lsa_slot_register (&slot);
-
- ospf6_lsdb_hook[OSPF6_LSA_TYPE_ROUTER & OSPF6_LSTYPE_CODE_MASK].hook =
- ospf6_spf_database_hook;
-
- memset (&hook, 0, sizeof (hook));
- hook.name = "OriginateRouter";
- hook.hook_change = ospf6_lsa_router_hook_neighbor;
- ospf6_hook_register (&hook, &neighbor_hook);
-
- memset (&hook, 0, sizeof (hook));
- hook.name = "OriginateRouter";
- hook.hook_change = ospf6_lsa_router_hook_interface;
- ospf6_hook_register (&hook, &interface_hook);
-
- memset (&hook, 0, sizeof (hook));
- hook.name = "OriginateRouter";
- hook.hook_change = ospf6_lsa_router_hook_area;
- ospf6_hook_register (&hook, &area_hook);
-
- memset (&hook, 0, sizeof (hook));
- hook.name = "OriginateRouter";
- hook.hook_change = ospf6_lsa_router_hook_top;
- ospf6_hook_register (&hook, &top_hook);
-}
-
-/*******************************/
-/* RFC2740 3.4.3.2 Network-LSA */
-/*******************************/
-
-int
-ospf6_lsa_network_show (struct vty *vty, struct ospf6_lsa *lsa)
-{
- char *start, *end, *current;
- struct ospf6_network_lsa *network_lsa;
- u_int32_t *router_id;
- char buf[128], options[32];
-
- assert (lsa->header);
- network_lsa = (struct ospf6_network_lsa *) (lsa->header + 1);
- router_id = (u_int32_t *)(network_lsa + 1);
-
- ospf6_options_string (network_lsa->options, options, sizeof (options));
- vty_out (vty, " Options: %s%s", options, VTY_NEWLINE);
-
- start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
- end = (char *) lsa->header + ntohs (lsa->header->length);
- for (current = start; current + sizeof (u_int32_t) <= end;
- current += sizeof (u_int32_t))
- {
- router_id = (u_int32_t *) current;
- inet_ntop (AF_INET, router_id, buf, sizeof (buf));
- vty_out (vty, " Attached Router: %s%s", buf, VTY_NEWLINE);
- }
- return 0;
-}
-
-void
-ospf6_lsa_network_update (char *ifname)
-{
- char buffer [MAXLSASIZE];
- u_int16_t size;
- struct ospf6_lsa *old;
- struct interface *ifp;
- struct ospf6_interface *o6i;
- int count;
-
- struct ospf6_network_lsa *network_lsa;
- struct ospf6_neighbor *o6n;
- u_int32_t *router_id;
- listnode node;
-
- ifp = if_lookup_by_name (ifname);
- if (! ifp)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_warn ("Update Network: No such Interface: %s", ifname);
- return;
- }
-
- o6i = (struct ospf6_interface *) ifp->info;
- if (! o6i || ! o6i->area)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_warn ("Update Network: Interface not enabled: %s", ifname);
- return;
- }
-
- /* find previous LSA */
- old = ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_NETWORK),
- htonl (o6i->if_id),
- o6i->area->ospf6->router_id, o6i->area);
-
- /* Don't originate Network-LSA if not DR */
- if (o6i->state != IFS_DR)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Update Network: Interface %s is not DR",
- o6i->interface->name);
- if (old)
- ospf6_lsa_premature_aging (old);
- return;
- }
-
- /* If none of neighbor is adjacent to us */
- count = 0;
- o6i->foreach_nei (o6i, &count, NBS_FULL, ospf6_count_state);
- if (count == 0)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Update Network: Interface %s is Stub",
- o6i->interface->name);
- if (old)
- ospf6_lsa_premature_aging (old);
- return;
- }
-
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Update Network: Interface %s", o6i->interface->name);
-
- /* prepare buffer */
- memset (buffer, 0, sizeof (buffer));
- size = sizeof (struct ospf6_network_lsa);
- network_lsa = (struct ospf6_network_lsa *) buffer;
- router_id = (u_int32_t *)(network_lsa + 1);
-
- /* set fields of myself */
- *router_id++ = o6i->area->ospf6->router_id;
- size += sizeof (u_int32_t);
- network_lsa->options[0] |= o6i->area->options[0];
- network_lsa->options[1] |= o6i->area->options[1];
- network_lsa->options[2] |= o6i->area->options[2];
-
- /* Walk through neighbors */
- for (node = listhead (o6i->neighbor_list); node; nextnode (node))
- {
- o6n = (struct ospf6_neighbor *) getdata (node);
-
- if (o6n->state != NBS_FULL)
- continue;
-
- /* set this neighbor's Router-ID to LSA */
- *router_id++ = o6n->router_id;
- size += sizeof (u_int32_t);
-
- /* options field is logical OR */
- network_lsa->options[0] |= o6n->options[0];
- network_lsa->options[1] |= o6n->options[1];
- network_lsa->options[2] |= o6n->options[2];
- }
-
- ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_NETWORK),
- htonl (o6i->if_id), o6i->area->ospf6->router_id,
- (char *) network_lsa, size, o6i->area);
-}
-int
-ospf6_lsa_network_hook_neighbor (void *neighbor)
-{
- struct ospf6_neighbor *o6n = neighbor;
- ospf6_lsa_network_update (o6n->ospf6_interface->interface->name);
- return 0;
+ OSPF6_DEBUG_LSA_OFF (level);
+ return CMD_SUCCESS;
}
-int
-ospf6_lsa_network_hook_interface (void *interface)
-{
- struct ospf6_interface *o6i = interface;
- if (o6i->area)
- ospf6_lsa_network_update (o6i->interface->name);
- return 0;
-}
+ALIAS (no_debug_ospf6_lsa_sendrecv,
+ no_debug_ospf6_lsa_cmd,
+ "no debug ospf6 lsa",
+ NO_STR
+ DEBUG_STR
+ OSPF6_STR
+ "Debug Link State Advertisements (LSAs)\n"
+ );
int
-ospf6_lsa_network_refresh (void *old)
+config_write_ospf6_debug_lsa (struct vty *vty)
{
- struct ospf6_lsa *lsa = old;
- struct interface *ifp;
-
- ifp = if_lookup_by_index (ntohl (lsa->header->id));
- if (! ifp)
- ospf6_lsa_premature_aging (old);
+ if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_ALL)
+ vty_out (vty, "debug ospf6 lsa all%s", VTY_NEWLINE);
else
- ospf6_lsa_network_update (ifp->name);
-
- return 0;
-}
-
-void
-ospf6_lsa_slot_register_network ()
-{
- struct ospf6_lsa_slot slot;
- struct ospf6_hook hook;
-
- memset (&slot, 0, sizeof (struct ospf6_lsa_slot));
- slot.type = htons (OSPF6_LSA_TYPE_NETWORK);
- slot.name = "Network";
- slot.func_show = ospf6_lsa_network_show;
- slot.func_refresh = ospf6_lsa_network_refresh;
- ospf6_lsa_slot_register (&slot);
-
- ospf6_lsdb_hook[OSPF6_LSA_TYPE_NETWORK & OSPF6_LSTYPE_CODE_MASK].hook =
- ospf6_spf_database_hook;
-
- memset (&hook, 0, sizeof (hook));
- hook.name = "OriginateNetwork";
- hook.hook_change = ospf6_lsa_network_hook_neighbor;
- ospf6_hook_register (&hook, &neighbor_hook);
-
- memset (&hook, 0, sizeof (hook));
- hook.name = "OriginateNetwork";
- hook.hook_change = ospf6_lsa_network_hook_interface;
- ospf6_hook_register (&hook, &interface_hook);
-}
-
-/****************************/
-/* RFC2740 3.4.3.6 Link-LSA */
-/****************************/
-
-int
-ospf6_lsa_link_show (struct vty *vty, struct ospf6_lsa *lsa)
-{
- char *start, *end, *current;
- struct ospf6_link_lsa *link_lsa;
- int prefixnum;
- struct ospf6_prefix *prefix;
- char buf[128];
- struct in6_addr in6;
-
- assert (lsa->header);
-
- link_lsa = (struct ospf6_link_lsa *) (lsa->header + 1);
- prefixnum = ntohl (link_lsa->llsa_prefix_num);
-
- inet_ntop (AF_INET6, (void *)&link_lsa->llsa_linklocal, buf, sizeof (buf));
- vty_out (vty, " LinkLocal Address: %s%s", buf, VTY_NEWLINE);
- vty_out (vty, " Number of Prefix: %d%s", prefixnum, VTY_NEWLINE);
-
- start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
- end = (char *) lsa->header + ntohs (lsa->header->length);
- for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
- {
- prefix = (struct ospf6_prefix *) current;
- if (current + OSPF6_PREFIX_SIZE (prefix) > end)
- {
- vty_out (vty, " Trailing %d byte garbage ... Malformed%s",
- end - current, VTY_NEWLINE);
- return -1;
- }
-
- ospf6_prefix_options_str (prefix->prefix_options, buf, sizeof (buf));
- vty_out (vty, " Prefix Options: %s%s", buf, VTY_NEWLINE);
- ospf6_prefix_in6_addr (prefix, &in6);
- inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
- vty_out (vty, " Prefix: %s/%d%s",
- buf, prefix->prefix_length, VTY_NEWLINE);
- }
-
- return 0;
-}
-
-
-void
-ospf6_lsa_link_update (char *ifname)
-{
- char *cp, buffer [MAXLSASIZE], buf[32];
- u_int16_t size;
- struct ospf6_lsa *old;
- struct interface *ifp;
- struct ospf6_interface *o6i;
-
- struct ospf6_link_lsa *link_lsa;
- struct ospf6_prefix *p;
- list prefix_connected;
- listnode node;
- struct connected *c;
-
- ifp = if_lookup_by_name (ifname);
- if (! ifp)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Update Link: No such Interface: %s", ifname);
- return;
- }
-
- o6i = (struct ospf6_interface *) ifp->info;
- if (! o6i || ! o6i->area)
{
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Update Link: Interface not enabled: %s", ifname);
- return;
- }
-
-#if 0
- /* Link-LSA is on Broadcast or NBMA */
- if (! if_is_broadcast (o6i->interface) /* && ! NBMA xxx */)
- {
- return;
- }
-#endif /*0*/
-
- /* find previous LSA */
- old = ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_LINK), htonl (o6i->if_id),
- ospf6->router_id, o6i->area);
-
- /* can't make Link-LSA if linklocal address not set */
- if (! o6i->lladdr)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_warn ("Update Link: No Linklocal Address: %s",
- o6i->interface->name);
- if (old)
- ospf6_lsa_premature_aging (old);
- return;
- }
-
- if (IS_OSPF6_DUMP_LSA)
- zlog_info ("Update Link: Interface %s", o6i->interface->name);
-
- if (! ospf6_interface_is_enabled (o6i->interface->ifindex))
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_info (" Interface %s not enabled", o6i->interface->name);
- if (old)
- ospf6_lsa_premature_aging (old);
- return;
- }
-
- /* check connected prefix */
- prefix_connected = list_new ();
- for (node = listhead (o6i->interface->connected); node; nextnode (node))
- {
- c = (struct connected *) getdata (node);
-
- /* filter prefix not IPv6 */
- if (c->address->family != AF_INET6)
- continue;
-
- /* for log */
- prefix2str (c->address, buf, sizeof (buf));
-
- CONTINUE_IF_ADDRESS_LINKLOCAL (c->address);
- CONTINUE_IF_ADDRESS_UNSPECIFIED (c->address);
- CONTINUE_IF_ADDRESS_LOOPBACK (c->address);
- CONTINUE_IF_ADDRESS_V4COMPAT (c->address);
- CONTINUE_IF_ADDRESS_V4MAPPED (c->address);
-
- /* filter prefix specified by configuration */
- if (o6i->plist_name)
+ if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_DEFAULT)
+ vty_out (vty, "debug ospf6 lsa%s", VTY_NEWLINE);
+ else
{
- struct prefix_list *plist;
- enum prefix_list_type result = PREFIX_PERMIT;
-
- plist = prefix_list_lookup (AFI_IP6, o6i->plist_name);
- if (plist)
- result = prefix_list_apply (plist, c->address);
- else if (IS_OSPF6_DUMP_LSA)
- zlog_warn ("Update Intra-Prefix (Stub): "
- "Prefix list \"%s\" not found", o6i->plist_name);
-
- if (result == PREFIX_DENY)
- {
- if (IS_OSPF6_DUMP_LSA)
- zlog_info (" Filter out Prefix-list %s: %s",
- o6i->plist_name, buf);
- continue;
- }
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ vty_out (vty, "debug ospf6 lsa send%s", VTY_NEWLINE);
+ if (IS_OSPF6_DEBUG_LSA (RECV))
+ vty_out (vty, "debug ospf6 lsa recv%s", VTY_NEWLINE);
+ if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+ vty_out (vty, "debug ospf6 lsa originate%s", VTY_NEWLINE);
+ if (IS_OSPF6_DEBUG_LSA (TIMER))
+ vty_out (vty, "debug ospf6 lsa timer%s", VTY_NEWLINE);
}
- if (IS_OSPF6_DUMP_LSA)
- zlog_info (" Advertise %s", buf);
-
- /* hold prefix in list. duplicate is filtered in ospf6_prefix_add() */
- p = ospf6_prefix_create (0, 0, (struct prefix_ipv6 *) c->address);
- ospf6_prefix_add (prefix_connected, p);
- }
-
- /* Note: even if no prefix configured, still we have to create Link-LSA
- for next-hop resolution */
-
- memset (buffer, 0, sizeof (buffer));
- size = sizeof (struct ospf6_link_lsa);
- link_lsa = (struct ospf6_link_lsa *) buffer;
-
- /* fill Link LSA and calculate size */
- link_lsa->llsa_rtr_pri = o6i->priority;
- link_lsa->llsa_options[0] = o6i->area->options[0];
- link_lsa->llsa_options[1] = o6i->area->options[1];
- link_lsa->llsa_options[2] = o6i->area->options[2];
-
- /* linklocal address */
- memcpy (&link_lsa->llsa_linklocal, o6i->lladdr, sizeof (struct in6_addr));
-
-#ifdef KAME /* clear ifindex */
- if (link_lsa->llsa_linklocal.s6_addr[3] & 0x0f)
- link_lsa->llsa_linklocal.s6_addr[3] &= ~((char)0x0f);
-#endif /* KAME */
-
- link_lsa->llsa_prefix_num = htonl (listcount (prefix_connected));
- cp = (char *)(link_lsa + 1);
- for (node = listhead (prefix_connected); node; nextnode (node))
- {
- p = (struct ospf6_prefix *) getdata (node);
- size += OSPF6_PREFIX_SIZE (p);
- memcpy (cp, p, OSPF6_PREFIX_SIZE (p));
- cp += OSPF6_PREFIX_SIZE (p);
+ if (IS_OSPF6_DEBUG_LSA (DATABASE))
+ vty_out (vty, "debug ospf6 lsa database%s", VTY_NEWLINE);
+ if (IS_OSPF6_DEBUG_LSA (MEMORY))
+ vty_out (vty, "debug ospf6 lsa memory%s", VTY_NEWLINE);
}
- for (node = listhead (prefix_connected); node; nextnode (node))
- {
- p = (struct ospf6_prefix *) getdata (node);
- ospf6_prefix_delete (p);
- }
- list_delete (prefix_connected);
-
- ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_LINK),
- htonl (o6i->if_id), o6i->area->ospf6->router_id,
- (char *) link_lsa, size, o6i);
-}
-
-int
-ospf6_lsa_link_hook_interface (void *interface)
-{
- struct ospf6_interface *o6i = interface;
- if (o6i->area)
- ospf6_lsa_link_update (o6i->interface->name);
- return 0;
-}
-
-int
-ospf6_lsa_link_refresh (void *old)
-{
- struct ospf6_lsa *lsa = old;
- struct interface *ifp;
-
- ifp = if_lookup_by_index (ntohl (lsa->header->id));
- if (! ifp)
- ospf6_lsa_premature_aging (old);
- else
- ospf6_lsa_link_update (ifp->name);
-
return 0;
}
void
-ospf6_lsa_slot_register_link ()
+install_element_ospf6_debug_lsa ()
{
- struct ospf6_lsa_slot slot;
-
- memset (&slot, 0, sizeof (struct ospf6_lsa_slot));
- slot.type = htons (OSPF6_LSA_TYPE_LINK);
- slot.name = "Link";
- slot.func_show = ospf6_lsa_link_show;
- slot.func_refresh = ospf6_lsa_link_refresh;
- slot.hook_interface.name = "OriginateLink";
- slot.hook_interface.hook_change = ospf6_lsa_link_hook_interface;
- ospf6_lsa_slot_register (&slot);
-
- /*
- * Link LSA handling will be shift in ospf6_intra.c
- * Currently, only database hook only moved to ospf6_intra.c
- */
-#if 0
- ospf6_lsdb_hook[OSPF6_LSA_TYPE_LINK & OSPF6_LSTYPE_CODE_MASK].hook =
- ospf6_spf_database_hook;
-#endif /*0*/
+ install_element (ENABLE_NODE, &debug_ospf6_lsa_cmd);
+ install_element (ENABLE_NODE, &debug_ospf6_lsa_sendrecv_cmd);
+ install_element (ENABLE_NODE, &no_debug_ospf6_lsa_cmd);
+ install_element (ENABLE_NODE, &no_debug_ospf6_lsa_sendrecv_cmd);
+ install_element (CONFIG_NODE, &debug_ospf6_lsa_cmd);
+ install_element (CONFIG_NODE, &debug_ospf6_lsa_sendrecv_cmd);
+ install_element (CONFIG_NODE, &no_debug_ospf6_lsa_cmd);
+ install_element (CONFIG_NODE, &no_debug_ospf6_lsa_sendrecv_cmd);
}
-int
-ospf6_lsa_add_hook (void *data)
-{
- struct ospf6_lsa *lsa = data;
- struct ospf6_lsa_slot *sp;
-
- sp = ospf6_lsa_slot_get (lsa->header->type);
- if (sp)
- {
- CALL_CHANGE_HOOK (&sp->database_hook, lsa);
- }
- else
- zlog_warn ("Unknown LSA added to database: %s", lsa->str);
- return 0;
-}
-
-int
-ospf6_lsa_change_hook (void *data)
-{
- struct ospf6_lsa *lsa = data;
- struct ospf6_lsa_slot *sp;
-
- sp = ospf6_lsa_slot_get (lsa->header->type);
- if (sp)
- {
- CALL_CHANGE_HOOK (&sp->database_hook, lsa);
- }
- else
- zlog_warn ("Unknown LSA changed in database: %s", lsa->str);
- return 0;
-}
-
-int
-ospf6_lsa_remove_hook (void *data)
-{
- struct ospf6_lsa *lsa = data;
- struct ospf6_lsa_slot *sp;
-
- sp = ospf6_lsa_slot_get (lsa->header->type);
- if (sp)
- {
- CALL_REMOVE_HOOK (&sp->database_hook, lsa);
- }
- else
- zlog_warn ("Unknown LSA removed from database: %s", lsa->str);
- return 0;
-}
-
-/* Initialize LSA slots */
-void
-ospf6_lsa_init ()
-{
- struct ospf6_hook hook;
-
- slot_head = NULL;
- ospf6_lsa_slot_register_router ();
- ospf6_lsa_slot_register_network ();
- ospf6_lsa_slot_register_link ();
-#if 0
- ospf6_lsa_slot_register_intra_prefix ();
- ospf6_lsa_slot_register_as_external ();
-#endif /*0*/
-
- hook.name = "LSADatabaseHook";
- hook.hook_add = ospf6_lsa_add_hook;
- hook.hook_change = ospf6_lsa_change_hook;
- hook.hook_remove = ospf6_lsa_remove_hook;
- ospf6_hook_register (&hook, &database_hook);
-}