diff options
Diffstat (limited to 'ospf6d/ospf6_message.c')
| -rw-r--r-- | ospf6d/ospf6_message.c | 4507 | 
1 files changed, 2237 insertions, 2270 deletions
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 583ba2a022..aa5f05ce17 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -49,897 +49,872 @@  #include <netinet/ip6.h>  unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0}; -static const struct message ospf6_message_type_str [] = -{ -  { OSPF6_MESSAGE_TYPE_HELLO,    "Hello"    }, -  { OSPF6_MESSAGE_TYPE_DBDESC,   "DbDesc"   }, -  { OSPF6_MESSAGE_TYPE_LSREQ,    "LSReq"    }, -  { OSPF6_MESSAGE_TYPE_LSUPDATE, "LSUpdate" }, -  { OSPF6_MESSAGE_TYPE_LSACK,    "LSAck"    }, -  { 0 } -}; +static const struct message ospf6_message_type_str[] = { +	{OSPF6_MESSAGE_TYPE_HELLO, "Hello"}, +	{OSPF6_MESSAGE_TYPE_DBDESC, "DbDesc"}, +	{OSPF6_MESSAGE_TYPE_LSREQ, "LSReq"}, +	{OSPF6_MESSAGE_TYPE_LSUPDATE, "LSUpdate"}, +	{OSPF6_MESSAGE_TYPE_LSACK, "LSAck"}, +	{0}};  /* Minimum (besides the standard OSPF packet header) lengths for OSPF     packets of particular types, offset is the "type" field. */ -const u_int16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] = -{ -  0, -  OSPF6_HELLO_MIN_SIZE, -  OSPF6_DB_DESC_MIN_SIZE, -  OSPF6_LS_REQ_MIN_SIZE, -  OSPF6_LS_UPD_MIN_SIZE, -  OSPF6_LS_ACK_MIN_SIZE -}; +const u_int16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] = { +	0, +	OSPF6_HELLO_MIN_SIZE, +	OSPF6_DB_DESC_MIN_SIZE, +	OSPF6_LS_REQ_MIN_SIZE, +	OSPF6_LS_UPD_MIN_SIZE, +	OSPF6_LS_ACK_MIN_SIZE};  /* Minimum (besides the standard LSA header) lengths for LSAs of particular     types, offset is the "LSA function code" portion of "LSA type" field. */ -const u_int16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] = -{ -  0, -  /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE, -  /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE, -  /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE, -  /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE, -  /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, -  /* 0x2006 */ 0, -  /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, -  /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE, -  /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE -}; +const u_int16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] = { +	0, +	/* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE, +	/* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE, +	/* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE, +	/* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE, +	/* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, +	/* 0x2006 */ 0, +	/* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, +	/* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE, +	/* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE};  /* print functions */ -static void -ospf6_header_print (struct ospf6_header *oh) +static void ospf6_header_print(struct ospf6_header *oh)  { -  char router_id[16], area_id[16]; -  inet_ntop (AF_INET, &oh->router_id, router_id, sizeof (router_id)); -  inet_ntop (AF_INET, &oh->area_id, area_id, sizeof (area_id)); - -  zlog_debug ("    OSPFv%d Type:%d Len:%hu Router-ID:%s", -             oh->version, oh->type, ntohs (oh->length), router_id); -  zlog_debug ("    Area-ID:%s Cksum:%hx Instance-ID:%d", -             area_id, ntohs (oh->checksum), oh->instance_id); +	char router_id[16], area_id[16]; +	inet_ntop(AF_INET, &oh->router_id, router_id, sizeof(router_id)); +	inet_ntop(AF_INET, &oh->area_id, area_id, sizeof(area_id)); + +	zlog_debug("    OSPFv%d Type:%d Len:%hu Router-ID:%s", oh->version, +		   oh->type, ntohs(oh->length), router_id); +	zlog_debug("    Area-ID:%s Cksum:%hx Instance-ID:%d", area_id, +		   ntohs(oh->checksum), oh->instance_id);  } -void -ospf6_hello_print (struct ospf6_header *oh) +void ospf6_hello_print(struct ospf6_header *oh)  { -  struct ospf6_hello *hello; -  char options[16]; -  char drouter[16], bdrouter[16], neighbor[16]; -  char *p; - -  ospf6_header_print (oh); -  assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO); - -  hello = (struct ospf6_hello *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); - -  inet_ntop (AF_INET, &hello->drouter, drouter, sizeof (drouter)); -  inet_ntop (AF_INET, &hello->bdrouter, bdrouter, sizeof (bdrouter)); -  ospf6_options_printbuf (hello->options, options, sizeof (options)); - -  zlog_debug ("    I/F-Id:%ld Priority:%d Option:%s", -             (u_long) ntohl (hello->interface_id), hello->priority, options); -  zlog_debug ("    HelloInterval:%hu DeadInterval:%hu", -             ntohs (hello->hello_interval), ntohs (hello->dead_interval)); -  zlog_debug ("    DR:%s BDR:%s", drouter, bdrouter); - -  for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello)); -       p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh); -       p += sizeof (u_int32_t)) -    { -      inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor)); -      zlog_debug ("    Neighbor: %s", neighbor); -    } - -  assert (p == OSPF6_MESSAGE_END (oh)); +	struct ospf6_hello *hello; +	char options[16]; +	char drouter[16], bdrouter[16], neighbor[16]; +	char *p; + +	ospf6_header_print(oh); +	assert(oh->type == OSPF6_MESSAGE_TYPE_HELLO); + +	hello = (struct ospf6_hello *)((caddr_t)oh +				       + sizeof(struct ospf6_header)); + +	inet_ntop(AF_INET, &hello->drouter, drouter, sizeof(drouter)); +	inet_ntop(AF_INET, &hello->bdrouter, bdrouter, sizeof(bdrouter)); +	ospf6_options_printbuf(hello->options, options, sizeof(options)); + +	zlog_debug("    I/F-Id:%ld Priority:%d Option:%s", +		   (u_long)ntohl(hello->interface_id), hello->priority, +		   options); +	zlog_debug("    HelloInterval:%hu DeadInterval:%hu", +		   ntohs(hello->hello_interval), ntohs(hello->dead_interval)); +	zlog_debug("    DR:%s BDR:%s", drouter, bdrouter); + +	for (p = (char *)((caddr_t)hello + sizeof(struct ospf6_hello)); +	     p + sizeof(u_int32_t) <= OSPF6_MESSAGE_END(oh); +	     p += sizeof(u_int32_t)) { +		inet_ntop(AF_INET, (void *)p, neighbor, sizeof(neighbor)); +		zlog_debug("    Neighbor: %s", neighbor); +	} + +	assert(p == OSPF6_MESSAGE_END(oh));  } -void -ospf6_dbdesc_print (struct ospf6_header *oh) +void ospf6_dbdesc_print(struct ospf6_header *oh)  { -  struct ospf6_dbdesc *dbdesc; -  char options[16]; -  char *p; +	struct ospf6_dbdesc *dbdesc; +	char options[16]; +	char *p; -  ospf6_header_print (oh); -  assert (oh->type == OSPF6_MESSAGE_TYPE_DBDESC); +	ospf6_header_print(oh); +	assert(oh->type == OSPF6_MESSAGE_TYPE_DBDESC); -  dbdesc = (struct ospf6_dbdesc *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); +	dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh +					 + sizeof(struct ospf6_header)); -  ospf6_options_printbuf (dbdesc->options, options, sizeof (options)); +	ospf6_options_printbuf(dbdesc->options, options, sizeof(options)); -  zlog_debug ("    MBZ: %#x Option: %s IfMTU: %hu", -             dbdesc->reserved1, options, ntohs (dbdesc->ifmtu)); -  zlog_debug ("    MBZ: %#x Bits: %s%s%s SeqNum: %#lx", -             dbdesc->reserved2, -             (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"), -             (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"), -             (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"), -             (u_long) ntohl (dbdesc->seqnum)); +	zlog_debug("    MBZ: %#x Option: %s IfMTU: %hu", dbdesc->reserved1, +		   options, ntohs(dbdesc->ifmtu)); +	zlog_debug("    MBZ: %#x Bits: %s%s%s SeqNum: %#lx", dbdesc->reserved2, +		   (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"), +		   (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"), +		   (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"), +		   (u_long)ntohl(dbdesc->seqnum)); -  for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); -       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); -       p += sizeof (struct ospf6_lsa_header)) -    ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); +	for (p = (char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc)); +	     p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); +	     p += sizeof(struct ospf6_lsa_header)) +		ospf6_lsa_header_print_raw((struct ospf6_lsa_header *)p); -  assert (p == OSPF6_MESSAGE_END (oh)); +	assert(p == OSPF6_MESSAGE_END(oh));  } -void -ospf6_lsreq_print (struct ospf6_header *oh) +void ospf6_lsreq_print(struct ospf6_header *oh)  { -  char id[16], adv_router[16]; -  char *p; - -  ospf6_header_print (oh); -  assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ); - -  for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); -       p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh); -       p += sizeof (struct ospf6_lsreq_entry)) -    { -      struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *) p; -      inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router)); -      inet_ntop (AF_INET, &e->id, id, sizeof (id)); -      zlog_debug ("    [%s Id:%s Adv:%s]", -                 ospf6_lstype_name (e->type), id, adv_router); -    } - -  assert (p == OSPF6_MESSAGE_END (oh)); +	char id[16], adv_router[16]; +	char *p; + +	ospf6_header_print(oh); +	assert(oh->type == OSPF6_MESSAGE_TYPE_LSREQ); + +	for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header)); +	     p + sizeof(struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END(oh); +	     p += sizeof(struct ospf6_lsreq_entry)) { +		struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *)p; +		inet_ntop(AF_INET, &e->adv_router, adv_router, +			  sizeof(adv_router)); +		inet_ntop(AF_INET, &e->id, id, sizeof(id)); +		zlog_debug("    [%s Id:%s Adv:%s]", ospf6_lstype_name(e->type), +			   id, adv_router); +	} + +	assert(p == OSPF6_MESSAGE_END(oh));  } -void -ospf6_lsupdate_print (struct ospf6_header *oh) +void ospf6_lsupdate_print(struct ospf6_header *oh)  { -  struct ospf6_lsupdate *lsupdate; -  u_long num; -  char *p; +	struct ospf6_lsupdate *lsupdate; +	u_long num; +	char *p; -  ospf6_header_print (oh); -  assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE); +	ospf6_header_print(oh); +	assert(oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE); -  lsupdate = (struct ospf6_lsupdate *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); +	lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh +					     + sizeof(struct ospf6_header)); -  num = ntohl (lsupdate->lsa_number); -  zlog_debug ("    Number of LSA: %ld", num); +	num = ntohl(lsupdate->lsa_number); +	zlog_debug("    Number of LSA: %ld", num); -  for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); -       p < OSPF6_MESSAGE_END (oh) && -       p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh); -       p += OSPF6_LSA_SIZE (p)) -    { -      ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); -    } +	for (p = (char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); +	     p < OSPF6_MESSAGE_END(oh) +	     && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh); +	     p += OSPF6_LSA_SIZE(p)) { +		ospf6_lsa_header_print_raw((struct ospf6_lsa_header *)p); +	} -  assert (p == OSPF6_MESSAGE_END (oh)); +	assert(p == OSPF6_MESSAGE_END(oh));  } -void -ospf6_lsack_print (struct ospf6_header *oh) +void ospf6_lsack_print(struct ospf6_header *oh)  { -  char *p; +	char *p; -  ospf6_header_print (oh); -  assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK); +	ospf6_header_print(oh); +	assert(oh->type == OSPF6_MESSAGE_TYPE_LSACK); -  for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); -       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); -       p += sizeof (struct ospf6_lsa_header)) -    ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); +	for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header)); +	     p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); +	     p += sizeof(struct ospf6_lsa_header)) +		ospf6_lsa_header_print_raw((struct ospf6_lsa_header *)p); -  assert (p == OSPF6_MESSAGE_END (oh)); +	assert(p == OSPF6_MESSAGE_END(oh));  } -static void -ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst, -                  struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst, +			     struct ospf6_interface *oi, +			     struct ospf6_header *oh)  { -  struct ospf6_hello *hello; -  struct ospf6_neighbor *on; -  char *p; -  int twoway = 0; -  int neighborchange = 0; -  int neighbor_ifindex_change = 0; -  int backupseen = 0; - -  hello = (struct ospf6_hello *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); - -  /* HelloInterval check */ -  if (ntohs (hello->hello_interval) != oi->hello_interval) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("HelloInterval mismatch"); -      return; -    } - -  /* RouterDeadInterval check */ -  if (ntohs (hello->dead_interval) != oi->dead_interval) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("RouterDeadInterval mismatch"); -      return; -    } - -  /* E-bit check */ -  if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) != -      OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E)) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("E-bit mismatch"); -      return; -    } - -  /* Find neighbor, create if not exist */ -  on = ospf6_neighbor_lookup (oh->router_id, oi); -  if (on == NULL) -    { -      on = ospf6_neighbor_create (oh->router_id, oi); -      on->prev_drouter = on->drouter = hello->drouter; -      on->prev_bdrouter = on->bdrouter = hello->bdrouter; -      on->priority = hello->priority; -    } - -  /* Always override neighbor's source address */ -  memcpy (&on->linklocal_addr, src, sizeof (struct in6_addr)); - -  /* Neighbor ifindex check */ -  if (on->ifindex != (ifindex_t)ntohl (hello->interface_id)) -    { -      on->ifindex = ntohl (hello->interface_id); -      neighbor_ifindex_change++; -    } - -  /* TwoWay check */ -  for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello)); -       p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh); -       p += sizeof (u_int32_t)) -    { -      u_int32_t *router_id = (u_int32_t *) p; - -      if (*router_id == oi->area->ospf6->router_id) -        twoway++; -    } - -  assert (p == OSPF6_MESSAGE_END (oh)); - -  /* RouterPriority check */ -  if (on->priority != hello->priority) -    { -      on->priority = hello->priority; -      neighborchange++; -    } - -  /* DR check */ -  if (on->drouter != hello->drouter) -    { -      on->prev_drouter = on->drouter; -      on->drouter = hello->drouter; -      if (on->prev_drouter == on->router_id || on->drouter == on->router_id) -        neighborchange++; -    } - -  /* BDR check */ -  if (on->bdrouter != hello->bdrouter) -    { -      on->prev_bdrouter = on->bdrouter; -      on->bdrouter = hello->bdrouter; -      if (on->prev_bdrouter == on->router_id || on->bdrouter == on->router_id) -        neighborchange++; -    } - -  /* BackupSeen check */ -  if (oi->state == OSPF6_INTERFACE_WAITING) -    { -      if (hello->bdrouter == on->router_id) -        backupseen++; -      else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0)) -        backupseen++; -    } - -  /* Execute neighbor events */ -  thread_execute (master, hello_received, on, 0); -  if (twoway) -    thread_execute (master, twoway_received, on, 0); -  else -    thread_execute (master, oneway_received, on, 0); - -  /* Schedule interface events */ -  if (backupseen) -    thread_add_event (master, backup_seen, oi, 0, NULL); -  if (neighborchange) -    thread_add_event (master, neighbor_change, oi, 0, NULL); - -  if (neighbor_ifindex_change && on->state == OSPF6_NEIGHBOR_FULL) -    OSPF6_ROUTER_LSA_SCHEDULE (oi->area); +	struct ospf6_hello *hello; +	struct ospf6_neighbor *on; +	char *p; +	int twoway = 0; +	int neighborchange = 0; +	int neighbor_ifindex_change = 0; +	int backupseen = 0; + +	hello = (struct ospf6_hello *)((caddr_t)oh +				       + sizeof(struct ospf6_header)); + +	/* HelloInterval check */ +	if (ntohs(hello->hello_interval) != oi->hello_interval) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("HelloInterval mismatch"); +		return; +	} + +	/* RouterDeadInterval check */ +	if (ntohs(hello->dead_interval) != oi->dead_interval) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("RouterDeadInterval mismatch"); +		return; +	} + +	/* E-bit check */ +	if (OSPF6_OPT_ISSET(hello->options, OSPF6_OPT_E) +	    != OSPF6_OPT_ISSET(oi->area->options, OSPF6_OPT_E)) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("E-bit mismatch"); +		return; +	} + +	/* Find neighbor, create if not exist */ +	on = ospf6_neighbor_lookup(oh->router_id, oi); +	if (on == NULL) { +		on = ospf6_neighbor_create(oh->router_id, oi); +		on->prev_drouter = on->drouter = hello->drouter; +		on->prev_bdrouter = on->bdrouter = hello->bdrouter; +		on->priority = hello->priority; +	} + +	/* Always override neighbor's source address */ +	memcpy(&on->linklocal_addr, src, sizeof(struct in6_addr)); + +	/* Neighbor ifindex check */ +	if (on->ifindex != (ifindex_t)ntohl(hello->interface_id)) { +		on->ifindex = ntohl(hello->interface_id); +		neighbor_ifindex_change++; +	} + +	/* TwoWay check */ +	for (p = (char *)((caddr_t)hello + sizeof(struct ospf6_hello)); +	     p + sizeof(u_int32_t) <= OSPF6_MESSAGE_END(oh); +	     p += sizeof(u_int32_t)) { +		u_int32_t *router_id = (u_int32_t *)p; + +		if (*router_id == oi->area->ospf6->router_id) +			twoway++; +	} + +	assert(p == OSPF6_MESSAGE_END(oh)); + +	/* RouterPriority check */ +	if (on->priority != hello->priority) { +		on->priority = hello->priority; +		neighborchange++; +	} + +	/* DR check */ +	if (on->drouter != hello->drouter) { +		on->prev_drouter = on->drouter; +		on->drouter = hello->drouter; +		if (on->prev_drouter == on->router_id +		    || on->drouter == on->router_id) +			neighborchange++; +	} + +	/* BDR check */ +	if (on->bdrouter != hello->bdrouter) { +		on->prev_bdrouter = on->bdrouter; +		on->bdrouter = hello->bdrouter; +		if (on->prev_bdrouter == on->router_id +		    || on->bdrouter == on->router_id) +			neighborchange++; +	} + +	/* BackupSeen check */ +	if (oi->state == OSPF6_INTERFACE_WAITING) { +		if (hello->bdrouter == on->router_id) +			backupseen++; +		else if (hello->drouter == on->router_id +			 && hello->bdrouter == htonl(0)) +			backupseen++; +	} + +	/* Execute neighbor events */ +	thread_execute(master, hello_received, on, 0); +	if (twoway) +		thread_execute(master, twoway_received, on, 0); +	else +		thread_execute(master, oneway_received, on, 0); + +	/* Schedule interface events */ +	if (backupseen) +		thread_add_event(master, backup_seen, oi, 0, NULL); +	if (neighborchange) +		thread_add_event(master, neighbor_change, oi, 0, NULL); + +	if (neighbor_ifindex_change && on->state == OSPF6_NEIGHBOR_FULL) +		OSPF6_ROUTER_LSA_SCHEDULE(oi->area);  } -static void -ospf6_dbdesc_recv_master (struct ospf6_header *oh, -                          struct ospf6_neighbor *on) +static void ospf6_dbdesc_recv_master(struct ospf6_header *oh, +				     struct ospf6_neighbor *on)  { -  struct ospf6_dbdesc *dbdesc; -  char *p; - -  dbdesc = (struct ospf6_dbdesc *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); - -  if (on->state < OSPF6_NEIGHBOR_INIT) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor state less than Init, ignore"); -      return; -    } - -  switch (on->state) -    { -    case OSPF6_NEIGHBOR_TWOWAY: -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor state is 2-Way, ignore"); -      return; - -    case OSPF6_NEIGHBOR_INIT: -      thread_execute (master, twoway_received, on, 0); -      if (on->state != OSPF6_NEIGHBOR_EXSTART) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Neighbor state is not ExStart, ignore"); -          return; -        } -      /* else fall through to ExStart */ -      /* fallthru */ -    case OSPF6_NEIGHBOR_EXSTART: -      /* if neighbor obeys us as our slave, schedule negotiation_done -         and process LSA Headers. Otherwise, ignore this message */ -      if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) && -          ! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) && -          ntohl (dbdesc->seqnum) == on->dbdesc_seqnum) -        { -          /* execute NegotiationDone */ -          thread_execute (master, negotiation_done, on, 0); - -          /* Record neighbor options */ -          memcpy (on->options, dbdesc->options, sizeof (on->options)); -        } -      else -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Negotiation failed"); -          return; -        } -      /* fall through to exchange */ - -    case OSPF6_NEIGHBOR_EXCHANGE: -      if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) -        { -          /* Duplicated DatabaseDescription is dropped by master */ -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Duplicated dbdesc discarded by Master, ignore"); -          return; -        } - -      if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT)) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Master/Slave bit mismatch"); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } - -      if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT)) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Initialize bit mismatch"); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } - -      if (memcmp (on->options, dbdesc->options, sizeof (on->options))) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Option field mismatch"); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } - -      if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Sequence number mismatch (%#lx expected)", -                       (u_long) on->dbdesc_seqnum); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } -      break; - -    case OSPF6_NEIGHBOR_LOADING: -    case OSPF6_NEIGHBOR_FULL: -      if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) -        { -          /* Duplicated DatabaseDescription is dropped by master */ -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Duplicated dbdesc discarded by Master, ignore"); -          return; -        } - -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Not duplicate dbdesc in state %s", -		    ospf6_neighbor_state_str[on->state]); -      thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -      return; - -    default: -      assert (0); -      break; -    } - -  /* Process LSA headers */ -  for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); -       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); -       p += sizeof (struct ospf6_lsa_header)) -    { -      struct ospf6_lsa *his, *mine; -      struct ospf6_lsdb *lsdb = NULL; - -      his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p); - -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("%s", his->name); - -      switch (OSPF6_LSA_SCOPE (his->header->type)) -        { -        case OSPF6_SCOPE_LINKLOCAL: -          lsdb = on->ospf6_if->lsdb; -          break; -        case OSPF6_SCOPE_AREA: -          lsdb = on->ospf6_if->area->lsdb; -          break; -        case OSPF6_SCOPE_AS: -          lsdb = on->ospf6_if->area->ospf6->lsdb; -          break; -        case OSPF6_SCOPE_RESERVED: -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Ignoring LSA of reserved scope"); -          ospf6_lsa_delete (his); -          continue; -          break; -        } - -      if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL && -          IS_AREA_STUB (on->ospf6_if->area)) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("SeqNumMismatch (E-bit mismatch), discard"); -          ospf6_lsa_delete (his); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } - -      mine = ospf6_lsdb_lookup (his->header->type, his->header->id, -                                his->header->adv_router, lsdb); -      if (mine == NULL) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Add request (No database copy)"); -          ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list); -        } -      else if (ospf6_lsa_compare (his, mine) < 0) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Add request (Received MoreRecent)"); -          ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list); -        } -      else -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Discard (Existing MoreRecent)"); -        } -      ospf6_lsa_delete (his); -    } - -  assert (p == OSPF6_MESSAGE_END (oh)); - -  /* Increment sequence number */ -  on->dbdesc_seqnum ++; - -  /* schedule send lsreq */ -  if (on->request_list->count) -    thread_add_event (master, ospf6_lsreq_send, on, 0, &on->thread_send_lsreq); - -  THREAD_OFF (on->thread_send_dbdesc); - -  /* More bit check */ -  if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) && -      ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT)) -    thread_add_event (master, exchange_done, on, 0, NULL); -  else { -    on->thread_send_dbdesc = NULL; -    thread_add_event(master, ospf6_dbdesc_send_newone, on, 0, -                     &on->thread_send_dbdesc); -  } - -  /* save last received dbdesc */ -  memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc)); +	struct ospf6_dbdesc *dbdesc; +	char *p; + +	dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh +					 + sizeof(struct ospf6_header)); + +	if (on->state < OSPF6_NEIGHBOR_INIT) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor state less than Init, ignore"); +		return; +	} + +	switch (on->state) { +	case OSPF6_NEIGHBOR_TWOWAY: +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor state is 2-Way, ignore"); +		return; + +	case OSPF6_NEIGHBOR_INIT: +		thread_execute(master, twoway_received, on, 0); +		if (on->state != OSPF6_NEIGHBOR_EXSTART) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug( +					"Neighbor state is not ExStart, ignore"); +			return; +		} +	/* else fall through to ExStart */ +	/* fallthru */ +	case OSPF6_NEIGHBOR_EXSTART: +		/* if neighbor obeys us as our slave, schedule negotiation_done +		   and process LSA Headers. Otherwise, ignore this message */ +		if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT) +		    && !CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT) +		    && ntohl(dbdesc->seqnum) == on->dbdesc_seqnum) { +			/* execute NegotiationDone */ +			thread_execute(master, negotiation_done, on, 0); + +			/* Record neighbor options */ +			memcpy(on->options, dbdesc->options, +			       sizeof(on->options)); +		} else { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Negotiation failed"); +			return; +		} +	/* fall through to exchange */ + +	case OSPF6_NEIGHBOR_EXCHANGE: +		if (!memcmp(dbdesc, &on->dbdesc_last, +			    sizeof(struct ospf6_dbdesc))) { +			/* Duplicated DatabaseDescription is dropped by master +			 */ +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug( +					"Duplicated dbdesc discarded by Master, ignore"); +			return; +		} + +		if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Master/Slave bit mismatch"); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} + +		if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Initialize bit mismatch"); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} + +		if (memcmp(on->options, dbdesc->options, sizeof(on->options))) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Option field mismatch"); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} + +		if (ntohl(dbdesc->seqnum) != on->dbdesc_seqnum) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug( +					"Sequence number mismatch (%#lx expected)", +					(u_long)on->dbdesc_seqnum); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} +		break; + +	case OSPF6_NEIGHBOR_LOADING: +	case OSPF6_NEIGHBOR_FULL: +		if (!memcmp(dbdesc, &on->dbdesc_last, +			    sizeof(struct ospf6_dbdesc))) { +			/* Duplicated DatabaseDescription is dropped by master +			 */ +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug( +					"Duplicated dbdesc discarded by Master, ignore"); +			return; +		} + +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Not duplicate dbdesc in state %s", +				   ospf6_neighbor_state_str[on->state]); +		thread_add_event(master, seqnumber_mismatch, on, 0, NULL); +		return; + +	default: +		assert(0); +		break; +	} + +	/* Process LSA headers */ +	for (p = (char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc)); +	     p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); +	     p += sizeof(struct ospf6_lsa_header)) { +		struct ospf6_lsa *his, *mine; +		struct ospf6_lsdb *lsdb = NULL; + +		his = ospf6_lsa_create_headeronly((struct ospf6_lsa_header *)p); + +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("%s", his->name); + +		switch (OSPF6_LSA_SCOPE(his->header->type)) { +		case OSPF6_SCOPE_LINKLOCAL: +			lsdb = on->ospf6_if->lsdb; +			break; +		case OSPF6_SCOPE_AREA: +			lsdb = on->ospf6_if->area->lsdb; +			break; +		case OSPF6_SCOPE_AS: +			lsdb = on->ospf6_if->area->ospf6->lsdb; +			break; +		case OSPF6_SCOPE_RESERVED: +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Ignoring LSA of reserved scope"); +			ospf6_lsa_delete(his); +			continue; +			break; +		} + +		if (ntohs(his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL +		    && IS_AREA_STUB(on->ospf6_if->area)) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug( +					"SeqNumMismatch (E-bit mismatch), discard"); +			ospf6_lsa_delete(his); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} + +		mine = ospf6_lsdb_lookup(his->header->type, his->header->id, +					 his->header->adv_router, lsdb); +		if (mine == NULL) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Add request (No database copy)"); +			ospf6_lsdb_add(ospf6_lsa_copy(his), on->request_list); +		} else if (ospf6_lsa_compare(his, mine) < 0) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Add request (Received MoreRecent)"); +			ospf6_lsdb_add(ospf6_lsa_copy(his), on->request_list); +		} else { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Discard (Existing MoreRecent)"); +		} +		ospf6_lsa_delete(his); +	} + +	assert(p == OSPF6_MESSAGE_END(oh)); + +	/* Increment sequence number */ +	on->dbdesc_seqnum++; + +	/* schedule send lsreq */ +	if (on->request_list->count) +		thread_add_event(master, ospf6_lsreq_send, on, 0, +				 &on->thread_send_lsreq); + +	THREAD_OFF(on->thread_send_dbdesc); + +	/* More bit check */ +	if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT) +	    && !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)) +		thread_add_event(master, exchange_done, on, 0, NULL); +	else { +		on->thread_send_dbdesc = NULL; +		thread_add_event(master, ospf6_dbdesc_send_newone, on, 0, +				 &on->thread_send_dbdesc); +	} + +	/* save last received dbdesc */ +	memcpy(&on->dbdesc_last, dbdesc, sizeof(struct ospf6_dbdesc));  } -static void -ospf6_dbdesc_recv_slave (struct ospf6_header *oh, -                         struct ospf6_neighbor *on) +static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh, +				    struct ospf6_neighbor *on)  { -  struct ospf6_dbdesc *dbdesc; -  char *p; - -  dbdesc = (struct ospf6_dbdesc *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); - -  if (on->state < OSPF6_NEIGHBOR_INIT) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor state less than Init, ignore"); -      return; -    } - -  switch (on->state) -    { -    case OSPF6_NEIGHBOR_TWOWAY: -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor state is 2-Way, ignore"); -      return; - -    case OSPF6_NEIGHBOR_INIT: -      thread_execute (master, twoway_received, on, 0); -      if (on->state != OSPF6_NEIGHBOR_EXSTART) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Neighbor state is not ExStart, ignore"); -          return; -        } -      /* else fall through to ExStart */ -      /* fallthru */ -    case OSPF6_NEIGHBOR_EXSTART: -      /* If the neighbor is Master, act as Slave. Schedule negotiation_done -         and process LSA Headers. Otherwise, ignore this message */ -      if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) && -          CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) && -          CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) && -          ntohs (oh->length) == sizeof (struct ospf6_header) + -                                sizeof (struct ospf6_dbdesc)) -        { -          /* set the master/slave bit to slave */ -          UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); - -          /* set the DD sequence number to one specified by master */ -          on->dbdesc_seqnum = ntohl (dbdesc->seqnum); - -          /* schedule NegotiationDone */ -          thread_execute (master, negotiation_done, on, 0); - -          /* Record neighbor options */ -          memcpy (on->options, dbdesc->options, sizeof (on->options)); -        } -      else -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Negotiation failed"); -          return; -        } -      break; - -    case OSPF6_NEIGHBOR_EXCHANGE: -      if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) -        { -          /* Duplicated DatabaseDescription causes slave to retransmit */ -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Duplicated dbdesc causes retransmit"); -          THREAD_OFF (on->thread_send_dbdesc); -          on->thread_send_dbdesc = NULL; -          thread_add_event(master, ospf6_dbdesc_send, on, 0, -                           &on->thread_send_dbdesc); -          return; -        } - -      if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT)) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Master/Slave bit mismatch"); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } - -      if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT)) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Initialize bit mismatch"); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } - -      if (memcmp (on->options, dbdesc->options, sizeof (on->options))) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Option field mismatch"); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } - -      if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum + 1) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Sequence number mismatch (%#lx expected)", -			(u_long) on->dbdesc_seqnum + 1); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } -      break; - -    case OSPF6_NEIGHBOR_LOADING: -    case OSPF6_NEIGHBOR_FULL: -      if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) -        { -          /* Duplicated DatabaseDescription causes slave to retransmit */ -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Duplicated dbdesc causes retransmit"); -          THREAD_OFF (on->thread_send_dbdesc); -          thread_add_event (master, ospf6_dbdesc_send, on, 0, &on->thread_send_dbdesc); -          return; -        } - -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Not duplicate dbdesc in state %s", -		    ospf6_neighbor_state_str[on->state]); -      thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -      return; - -    default: -      assert (0); -      break; -    } - -  /* Process LSA headers */ -  for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); -       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); -       p += sizeof (struct ospf6_lsa_header)) -    { -      struct ospf6_lsa *his, *mine; -      struct ospf6_lsdb *lsdb = NULL; - -      his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p); - -      switch (OSPF6_LSA_SCOPE (his->header->type)) -        { -        case OSPF6_SCOPE_LINKLOCAL: -          lsdb = on->ospf6_if->lsdb; -          break; -        case OSPF6_SCOPE_AREA: -          lsdb = on->ospf6_if->area->lsdb; -          break; -        case OSPF6_SCOPE_AS: -          lsdb = on->ospf6_if->area->ospf6->lsdb; -          break; -        case OSPF6_SCOPE_RESERVED: -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Ignoring LSA of reserved scope"); -          ospf6_lsa_delete (his); -          continue; -          break; -        } - -      if (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS && -          IS_AREA_STUB (on->ospf6_if->area)) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("E-bit mismatch with LSA Headers"); -          ospf6_lsa_delete (his); -          thread_add_event (master, seqnumber_mismatch, on, 0, NULL); -          return; -        } - -      mine = ospf6_lsdb_lookup (his->header->type, his->header->id, -                                his->header->adv_router, lsdb); -      if (mine == NULL || ospf6_lsa_compare (his, mine) < 0) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Add request-list: %s", his->name); -          ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list); -        } -      ospf6_lsa_delete (his); -    } - -  assert (p == OSPF6_MESSAGE_END (oh)); - -  /* Set sequence number to Master's */ -  on->dbdesc_seqnum = ntohl (dbdesc->seqnum); - -  /* schedule send lsreq */ -  if (on->request_list->count) -    thread_add_event (master, ospf6_lsreq_send, on, 0, &on->thread_send_lsreq); - -  THREAD_OFF (on->thread_send_dbdesc); -  thread_add_event (master, ospf6_dbdesc_send_newone, on, 0, &on->thread_send_dbdesc); - -  /* save last received dbdesc */ -  memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc)); +	struct ospf6_dbdesc *dbdesc; +	char *p; + +	dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh +					 + sizeof(struct ospf6_header)); + +	if (on->state < OSPF6_NEIGHBOR_INIT) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor state less than Init, ignore"); +		return; +	} + +	switch (on->state) { +	case OSPF6_NEIGHBOR_TWOWAY: +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor state is 2-Way, ignore"); +		return; + +	case OSPF6_NEIGHBOR_INIT: +		thread_execute(master, twoway_received, on, 0); +		if (on->state != OSPF6_NEIGHBOR_EXSTART) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug( +					"Neighbor state is not ExStart, ignore"); +			return; +		} +	/* else fall through to ExStart */ +	/* fallthru */ +	case OSPF6_NEIGHBOR_EXSTART: +		/* If the neighbor is Master, act as Slave. Schedule +		   negotiation_done +		   and process LSA Headers. Otherwise, ignore this message */ +		if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT) +		    && CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT) +		    && CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT) +		    && ntohs(oh->length) +			       == sizeof(struct ospf6_header) +					  + sizeof(struct ospf6_dbdesc)) { +			/* set the master/slave bit to slave */ +			UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); + +			/* set the DD sequence number to one specified by master +			 */ +			on->dbdesc_seqnum = ntohl(dbdesc->seqnum); + +			/* schedule NegotiationDone */ +			thread_execute(master, negotiation_done, on, 0); + +			/* Record neighbor options */ +			memcpy(on->options, dbdesc->options, +			       sizeof(on->options)); +		} else { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Negotiation failed"); +			return; +		} +		break; + +	case OSPF6_NEIGHBOR_EXCHANGE: +		if (!memcmp(dbdesc, &on->dbdesc_last, +			    sizeof(struct ospf6_dbdesc))) { +			/* Duplicated DatabaseDescription causes slave to +			 * retransmit */ +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug( +					"Duplicated dbdesc causes retransmit"); +			THREAD_OFF(on->thread_send_dbdesc); +			on->thread_send_dbdesc = NULL; +			thread_add_event(master, ospf6_dbdesc_send, on, 0, +					 &on->thread_send_dbdesc); +			return; +		} + +		if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Master/Slave bit mismatch"); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} + +		if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Initialize bit mismatch"); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} + +		if (memcmp(on->options, dbdesc->options, sizeof(on->options))) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Option field mismatch"); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} + +		if (ntohl(dbdesc->seqnum) != on->dbdesc_seqnum + 1) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug( +					"Sequence number mismatch (%#lx expected)", +					(u_long)on->dbdesc_seqnum + 1); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} +		break; + +	case OSPF6_NEIGHBOR_LOADING: +	case OSPF6_NEIGHBOR_FULL: +		if (!memcmp(dbdesc, &on->dbdesc_last, +			    sizeof(struct ospf6_dbdesc))) { +			/* Duplicated DatabaseDescription causes slave to +			 * retransmit */ +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug( +					"Duplicated dbdesc causes retransmit"); +			THREAD_OFF(on->thread_send_dbdesc); +			thread_add_event(master, ospf6_dbdesc_send, on, 0, +					 &on->thread_send_dbdesc); +			return; +		} + +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Not duplicate dbdesc in state %s", +				   ospf6_neighbor_state_str[on->state]); +		thread_add_event(master, seqnumber_mismatch, on, 0, NULL); +		return; + +	default: +		assert(0); +		break; +	} + +	/* Process LSA headers */ +	for (p = (char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc)); +	     p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); +	     p += sizeof(struct ospf6_lsa_header)) { +		struct ospf6_lsa *his, *mine; +		struct ospf6_lsdb *lsdb = NULL; + +		his = ospf6_lsa_create_headeronly((struct ospf6_lsa_header *)p); + +		switch (OSPF6_LSA_SCOPE(his->header->type)) { +		case OSPF6_SCOPE_LINKLOCAL: +			lsdb = on->ospf6_if->lsdb; +			break; +		case OSPF6_SCOPE_AREA: +			lsdb = on->ospf6_if->area->lsdb; +			break; +		case OSPF6_SCOPE_AS: +			lsdb = on->ospf6_if->area->ospf6->lsdb; +			break; +		case OSPF6_SCOPE_RESERVED: +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Ignoring LSA of reserved scope"); +			ospf6_lsa_delete(his); +			continue; +			break; +		} + +		if (OSPF6_LSA_SCOPE(his->header->type) == OSPF6_SCOPE_AS +		    && IS_AREA_STUB(on->ospf6_if->area)) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("E-bit mismatch with LSA Headers"); +			ospf6_lsa_delete(his); +			thread_add_event(master, seqnumber_mismatch, on, 0, +					 NULL); +			return; +		} + +		mine = ospf6_lsdb_lookup(his->header->type, his->header->id, +					 his->header->adv_router, lsdb); +		if (mine == NULL || ospf6_lsa_compare(his, mine) < 0) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Add request-list: %s", his->name); +			ospf6_lsdb_add(ospf6_lsa_copy(his), on->request_list); +		} +		ospf6_lsa_delete(his); +	} + +	assert(p == OSPF6_MESSAGE_END(oh)); + +	/* Set sequence number to Master's */ +	on->dbdesc_seqnum = ntohl(dbdesc->seqnum); + +	/* schedule send lsreq */ +	if (on->request_list->count) +		thread_add_event(master, ospf6_lsreq_send, on, 0, +				 &on->thread_send_lsreq); + +	THREAD_OFF(on->thread_send_dbdesc); +	thread_add_event(master, ospf6_dbdesc_send_newone, on, 0, +			 &on->thread_send_dbdesc); + +	/* save last received dbdesc */ +	memcpy(&on->dbdesc_last, dbdesc, sizeof(struct ospf6_dbdesc));  } -static void -ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst, -                   struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_dbdesc_recv(struct in6_addr *src, struct in6_addr *dst, +			      struct ospf6_interface *oi, +			      struct ospf6_header *oh)  { -  struct ospf6_neighbor *on; -  struct ospf6_dbdesc *dbdesc; - -  on = ospf6_neighbor_lookup (oh->router_id, oi); -  if (on == NULL) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor not found, ignore"); -      return; -    } - -  dbdesc = (struct ospf6_dbdesc *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); - -  /* Interface MTU check */ -  if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("I/F MTU mismatch"); -      return; -    } - -  if (dbdesc->reserved1 || dbdesc->reserved2) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Non-0 reserved field in %s's DbDesc, correct", -		    on->name); -      dbdesc->reserved1 = 0; -      dbdesc->reserved2 = 0; -    } - -  if (ntohl (oh->router_id) < ntohl (ospf6->router_id)) -    ospf6_dbdesc_recv_master (oh, on); -  else if (ntohl (ospf6->router_id) < ntohl (oh->router_id)) -    ospf6_dbdesc_recv_slave (oh, on); -  else -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Can't decide which is master, ignore"); -    } +	struct ospf6_neighbor *on; +	struct ospf6_dbdesc *dbdesc; + +	on = ospf6_neighbor_lookup(oh->router_id, oi); +	if (on == NULL) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor not found, ignore"); +		return; +	} + +	dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh +					 + sizeof(struct ospf6_header)); + +	/* Interface MTU check */ +	if (!oi->mtu_ignore && ntohs(dbdesc->ifmtu) != oi->ifmtu) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("I/F MTU mismatch"); +		return; +	} + +	if (dbdesc->reserved1 || dbdesc->reserved2) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug( +				"Non-0 reserved field in %s's DbDesc, correct", +				on->name); +		dbdesc->reserved1 = 0; +		dbdesc->reserved2 = 0; +	} + +	if (ntohl(oh->router_id) < ntohl(ospf6->router_id)) +		ospf6_dbdesc_recv_master(oh, on); +	else if (ntohl(ospf6->router_id) < ntohl(oh->router_id)) +		ospf6_dbdesc_recv_slave(oh, on); +	else { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Can't decide which is master, ignore"); +	}  } -static void -ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst, -                  struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_lsreq_recv(struct in6_addr *src, struct in6_addr *dst, +			     struct ospf6_interface *oi, +			     struct ospf6_header *oh)  { -  struct ospf6_neighbor *on; -  char *p; -  struct ospf6_lsreq_entry *e; -  struct ospf6_lsdb *lsdb = NULL; -  struct ospf6_lsa *lsa; - -  on = ospf6_neighbor_lookup (oh->router_id, oi); -  if (on == NULL) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor not found, ignore"); -      return; -    } - -  if (on->state != OSPF6_NEIGHBOR_EXCHANGE && -      on->state != OSPF6_NEIGHBOR_LOADING && -      on->state != OSPF6_NEIGHBOR_FULL) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor state less than Exchange, ignore"); -      return; -    } - -  /* Process each request */ -  for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); -       p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh); -       p += sizeof (struct ospf6_lsreq_entry)) -    { -      e = (struct ospf6_lsreq_entry *) p; - -      switch (OSPF6_LSA_SCOPE (e->type)) -        { -        case OSPF6_SCOPE_LINKLOCAL: -          lsdb = on->ospf6_if->lsdb; -          break; -        case OSPF6_SCOPE_AREA: -          lsdb = on->ospf6_if->area->lsdb; -          break; -        case OSPF6_SCOPE_AS: -          lsdb = on->ospf6_if->area->ospf6->lsdb; -          break; -        default: -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Ignoring LSA of reserved scope"); -          continue; -          break; -        } - -      /* Find database copy */ -      lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb); -      if (lsa == NULL) -        { -          char id[16], adv_router[16]; -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            { -              inet_ntop (AF_INET, &e->id, id, sizeof (id)); -              inet_ntop (AF_INET, &e->adv_router, adv_router, -                     sizeof (adv_router)); -              zlog_debug ("Can't find requested [%s Id:%s Adv:%s]", -			  ospf6_lstype_name (e->type), id, adv_router); -            } -          thread_add_event (master, bad_lsreq, on, 0, NULL); -          return; -        } - -      ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list); -    } - -  assert (p == OSPF6_MESSAGE_END (oh)); - -  /* schedule send lsupdate */ -  THREAD_OFF (on->thread_send_lsupdate); -  thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0, &on->thread_send_lsupdate); +	struct ospf6_neighbor *on; +	char *p; +	struct ospf6_lsreq_entry *e; +	struct ospf6_lsdb *lsdb = NULL; +	struct ospf6_lsa *lsa; + +	on = ospf6_neighbor_lookup(oh->router_id, oi); +	if (on == NULL) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor not found, ignore"); +		return; +	} + +	if (on->state != OSPF6_NEIGHBOR_EXCHANGE +	    && on->state != OSPF6_NEIGHBOR_LOADING +	    && on->state != OSPF6_NEIGHBOR_FULL) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor state less than Exchange, ignore"); +		return; +	} + +	/* Process each request */ +	for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header)); +	     p + sizeof(struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END(oh); +	     p += sizeof(struct ospf6_lsreq_entry)) { +		e = (struct ospf6_lsreq_entry *)p; + +		switch (OSPF6_LSA_SCOPE(e->type)) { +		case OSPF6_SCOPE_LINKLOCAL: +			lsdb = on->ospf6_if->lsdb; +			break; +		case OSPF6_SCOPE_AREA: +			lsdb = on->ospf6_if->area->lsdb; +			break; +		case OSPF6_SCOPE_AS: +			lsdb = on->ospf6_if->area->ospf6->lsdb; +			break; +		default: +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Ignoring LSA of reserved scope"); +			continue; +			break; +		} + +		/* Find database copy */ +		lsa = ospf6_lsdb_lookup(e->type, e->id, e->adv_router, lsdb); +		if (lsa == NULL) { +			char id[16], adv_router[16]; +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) { +				inet_ntop(AF_INET, &e->id, id, sizeof(id)); +				inet_ntop(AF_INET, &e->adv_router, adv_router, +					  sizeof(adv_router)); +				zlog_debug( +					"Can't find requested [%s Id:%s Adv:%s]", +					ospf6_lstype_name(e->type), id, +					adv_router); +			} +			thread_add_event(master, bad_lsreq, on, 0, NULL); +			return; +		} + +		ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->lsupdate_list); +	} + +	assert(p == OSPF6_MESSAGE_END(oh)); + +	/* schedule send lsupdate */ +	THREAD_OFF(on->thread_send_lsupdate); +	thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0, +			 &on->thread_send_lsupdate);  }  /* Verify, that the specified memory area contains exactly N valid IPv6     prefixes as specified by RFC5340, A.4.1. */ -static unsigned -ospf6_prefixes_examin -( -  struct ospf6_prefix *current, /* start of buffer    */ -  unsigned length, -  const u_int32_t req_num_pfxs  /* always compared with the actual number of prefixes */ -) +static unsigned ospf6_prefixes_examin( +	struct ospf6_prefix *current, /* start of buffer    */ +	unsigned length, +	const u_int32_t req_num_pfxs /* always compared with the actual number +					of prefixes */ +	)  { -  u_char requested_pfx_bytes; -  u_int32_t real_num_pfxs = 0; - -  while (length) -  { -    if (length < OSPF6_PREFIX_MIN_SIZE) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: undersized IPv6 prefix header", __func__); -      return MSG_NG; -    } -    /* safe to look deeper */ -    if (current->prefix_length > IPV6_MAX_BITLEN) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: invalid PrefixLength (%u bits)", __func__, current->prefix_length); -      return MSG_NG; -    } -    /* covers both fixed- and variable-sized fields */ -    requested_pfx_bytes = OSPF6_PREFIX_MIN_SIZE + OSPF6_PREFIX_SPACE (current->prefix_length); -    if (requested_pfx_bytes > length) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: undersized IPv6 prefix", __func__); -      return MSG_NG; -    } -    /* next prefix */ -    length -= requested_pfx_bytes; -    current = (struct ospf6_prefix *) ((caddr_t) current + requested_pfx_bytes); -    real_num_pfxs++; -  } -  if (real_num_pfxs != req_num_pfxs) -  { -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: IPv6 prefix number mismatch (%u required, %u real)", -                  __func__, req_num_pfxs, real_num_pfxs); -    return MSG_NG; -  } -  return MSG_OK; +	u_char requested_pfx_bytes; +	u_int32_t real_num_pfxs = 0; + +	while (length) { +		if (length < OSPF6_PREFIX_MIN_SIZE) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug("%s: undersized IPv6 prefix header", +					   __func__); +			return MSG_NG; +		} +		/* safe to look deeper */ +		if (current->prefix_length > IPV6_MAX_BITLEN) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug("%s: invalid PrefixLength (%u bits)", +					   __func__, current->prefix_length); +			return MSG_NG; +		} +		/* covers both fixed- and variable-sized fields */ +		requested_pfx_bytes = +			OSPF6_PREFIX_MIN_SIZE +			+ OSPF6_PREFIX_SPACE(current->prefix_length); +		if (requested_pfx_bytes > length) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug("%s: undersized IPv6 prefix", +					   __func__); +			return MSG_NG; +		} +		/* next prefix */ +		length -= requested_pfx_bytes; +		current = (struct ospf6_prefix *)((caddr_t)current +						  + requested_pfx_bytes); +		real_num_pfxs++; +	} +	if (real_num_pfxs != req_num_pfxs) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug( +				"%s: IPv6 prefix number mismatch (%u required, %u real)", +				__func__, req_num_pfxs, real_num_pfxs); +		return MSG_NG; +	} +	return MSG_OK;  }  /* Verify an LSA to have a valid length and dispatch further (where @@ -947,1374 +922,1378 @@ ospf6_prefixes_examin     is properly sized/aligned within the LSA. Note that this function gets     LSA type in network byte order, uses in host byte order and passes to     ospf6_lstype_name() in network byte order again. */ -static unsigned -ospf6_lsa_examin (struct ospf6_lsa_header *lsah, const u_int16_t lsalen, const u_char headeronly) +static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah, +				 const u_int16_t lsalen, +				 const u_char headeronly)  { -  struct ospf6_intra_prefix_lsa *intra_prefix_lsa; -  struct ospf6_as_external_lsa *as_external_lsa; -  struct ospf6_link_lsa *link_lsa; -  unsigned exp_length; -  u_int8_t ltindex; -  u_int16_t lsatype; - -  /* In case an additional minimum length constraint is defined for current -     LSA type, make sure that this constraint is met. */ -  lsatype = ntohs (lsah->type); -  ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK; -  if -  ( -    ltindex < OSPF6_LSTYPE_SIZE && -    ospf6_lsa_minlen[ltindex] && -    lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE -  ) -  { -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: undersized (%u B) LSA", __func__, lsalen); -    return MSG_NG; -  } -  switch (lsatype) -  { -  case OSPF6_LSTYPE_ROUTER: -    /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes followed -       by N>=0 interface descriptions. */ -    if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE) % OSPF6_ROUTER_LSDESC_FIX_SIZE) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: interface description alignment error", __func__); -      return MSG_NG; -    } -    break; -  case OSPF6_LSTYPE_NETWORK: -    /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes -       followed by N>=0 attached router descriptions. */ -    if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_NETWORK_LSA_MIN_SIZE) % OSPF6_NETWORK_LSDESC_FIX_SIZE) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: router description alignment error", __func__); -      return MSG_NG; -    } -    break; -  case OSPF6_LSTYPE_INTER_PREFIX: -    /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE bytes -       followed by 3-4 fields of a single IPv6 prefix. */ -    if (headeronly) -      break; -    return ospf6_prefixes_examin -    ( -      (struct ospf6_prefix *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_PREFIX_LSA_MIN_SIZE), -      lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTER_PREFIX_LSA_MIN_SIZE, -      1 -    ); -  case OSPF6_LSTYPE_INTER_ROUTER: -    /* RFC5340 A.4.6, fixed-size LSA. */ -    if (lsalen > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: oversized (%u B) LSA", __func__, lsalen); -      return MSG_NG; -    } -    break; -  case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */ -  case OSPF6_LSTYPE_TYPE_7: -    /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE bytes -       followed by 3-4 fields of IPv6 prefix and 3 conditional LSA fields: -       16 bytes of forwarding address, 4 bytes of external route tag, -       4 bytes of referenced link state ID. */ -    if (headeronly) -      break; -    as_external_lsa = (struct ospf6_as_external_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); -    exp_length = OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE; -    /* To find out if the last optional field (Referenced Link State ID) is -       assumed in this LSA, we need to access fixed fields of the IPv6 -       prefix before ospf6_prefix_examin() confirms its sizing. */ -    if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen); -      return MSG_NG; -    } -    /* forwarding address */ -    if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F)) -      exp_length += 16; -    /* external route tag */ -    if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T)) -      exp_length += 4; -    /* referenced link state ID */ -    if (as_external_lsa->prefix.u._prefix_referenced_lstype) -      exp_length += 4; -    /* All the fixed-size fields (mandatory and optional) must fit. I.e., -       this check does not include any IPv6 prefix fields. */ -    if (exp_length > lsalen) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen); -      return MSG_NG; -    } -    /* The last call completely covers the remainder (IPv6 prefix). */ -    return ospf6_prefixes_examin -    ( -      (struct ospf6_prefix *) ((caddr_t) as_external_lsa + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE), -      lsalen - exp_length, -      1 -    ); -  case OSPF6_LSTYPE_LINK: -    /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes followed -       by N>=0 IPv6 prefix blocks (with N declared beforehand). */ -    if (headeronly) -      break; -    link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); -    return ospf6_prefixes_examin -    ( -      (struct ospf6_prefix *) ((caddr_t) link_lsa + OSPF6_LINK_LSA_MIN_SIZE), -      lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_LINK_LSA_MIN_SIZE, -      ntohl (link_lsa->prefix_num) /* 32 bits */ -    ); -  case OSPF6_LSTYPE_INTRA_PREFIX: -  /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE bytes -     followed by N>=0 IPv6 prefixes (with N declared beforehand). */ -    if (headeronly) -      break; -    intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); -    return ospf6_prefixes_examin -    ( -      (struct ospf6_prefix *) ((caddr_t) intra_prefix_lsa + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE), -      lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE, -      ntohs (intra_prefix_lsa->prefix_num) /* 16 bits */ -    ); -  } -  /* No additional validation is possible for unknown LSA types, which are -     themselves valid in OPSFv3, hence the default decision is to accept. */ -  return MSG_OK; +	struct ospf6_intra_prefix_lsa *intra_prefix_lsa; +	struct ospf6_as_external_lsa *as_external_lsa; +	struct ospf6_link_lsa *link_lsa; +	unsigned exp_length; +	u_int8_t ltindex; +	u_int16_t lsatype; + +	/* In case an additional minimum length constraint is defined for +	   current +	   LSA type, make sure that this constraint is met. */ +	lsatype = ntohs(lsah->type); +	ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK; +	if (ltindex < OSPF6_LSTYPE_SIZE && ospf6_lsa_minlen[ltindex] +	    && lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug("%s: undersized (%u B) LSA", __func__, +				   lsalen); +		return MSG_NG; +	} +	switch (lsatype) { +	case OSPF6_LSTYPE_ROUTER: +		/* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes +		   followed +		   by N>=0 interface descriptions. */ +		if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE) +		    % OSPF6_ROUTER_LSDESC_FIX_SIZE) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug( +					"%s: interface description alignment error", +					__func__); +			return MSG_NG; +		} +		break; +	case OSPF6_LSTYPE_NETWORK: +		/* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes +		   followed by N>=0 attached router descriptions. */ +		if ((lsalen - OSPF6_LSA_HEADER_SIZE +		     - OSPF6_NETWORK_LSA_MIN_SIZE) +		    % OSPF6_NETWORK_LSDESC_FIX_SIZE) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug( +					"%s: router description alignment error", +					__func__); +			return MSG_NG; +		} +		break; +	case OSPF6_LSTYPE_INTER_PREFIX: +		/* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE +		   bytes +		   followed by 3-4 fields of a single IPv6 prefix. */ +		if (headeronly) +			break; +		return ospf6_prefixes_examin( +			(struct ospf6_prefix +				 *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE +				    + OSPF6_INTER_PREFIX_LSA_MIN_SIZE), +			lsalen - OSPF6_LSA_HEADER_SIZE +				- OSPF6_INTER_PREFIX_LSA_MIN_SIZE, +			1); +	case OSPF6_LSTYPE_INTER_ROUTER: +		/* RFC5340 A.4.6, fixed-size LSA. */ +		if (lsalen +		    > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug("%s: oversized (%u B) LSA", __func__, +					   lsalen); +			return MSG_NG; +		} +		break; +	case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */ +	case OSPF6_LSTYPE_TYPE_7: +		/* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE +		   bytes +		   followed by 3-4 fields of IPv6 prefix and 3 conditional LSA +		   fields: +		   16 bytes of forwarding address, 4 bytes of external route +		   tag, +		   4 bytes of referenced link state ID. */ +		if (headeronly) +			break; +		as_external_lsa = +			(struct ospf6_as_external_lsa +				 *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE); +		exp_length = +			OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE; +		/* To find out if the last optional field (Referenced Link State +		   ID) is +		   assumed in this LSA, we need to access fixed fields of the +		   IPv6 +		   prefix before ospf6_prefix_examin() confirms its sizing. */ +		if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug("%s: undersized (%u B) LSA header", +					   __func__, lsalen); +			return MSG_NG; +		} +		/* forwarding address */ +		if (CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F)) +			exp_length += 16; +		/* external route tag */ +		if (CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T)) +			exp_length += 4; +		/* referenced link state ID */ +		if (as_external_lsa->prefix.u._prefix_referenced_lstype) +			exp_length += 4; +		/* All the fixed-size fields (mandatory and optional) must fit. +		   I.e., +		   this check does not include any IPv6 prefix fields. */ +		if (exp_length > lsalen) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug("%s: undersized (%u B) LSA header", +					   __func__, lsalen); +			return MSG_NG; +		} +		/* The last call completely covers the remainder (IPv6 prefix). +		 */ +		return ospf6_prefixes_examin( +			(struct ospf6_prefix +				 *)((caddr_t)as_external_lsa +				    + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE), +			lsalen - exp_length, 1); +	case OSPF6_LSTYPE_LINK: +		/* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes +		   followed +		   by N>=0 IPv6 prefix blocks (with N declared beforehand). */ +		if (headeronly) +			break; +		link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsah +						     + OSPF6_LSA_HEADER_SIZE); +		return ospf6_prefixes_examin( +			(struct ospf6_prefix *)((caddr_t)link_lsa +						+ OSPF6_LINK_LSA_MIN_SIZE), +			lsalen - OSPF6_LSA_HEADER_SIZE +				- OSPF6_LINK_LSA_MIN_SIZE, +			ntohl(link_lsa->prefix_num) /* 32 bits */ +			); +	case OSPF6_LSTYPE_INTRA_PREFIX: +		/* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE +		   bytes +		   followed by N>=0 IPv6 prefixes (with N declared beforehand). +		   */ +		if (headeronly) +			break; +		intra_prefix_lsa = +			(struct ospf6_intra_prefix_lsa +				 *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE); +		return ospf6_prefixes_examin( +			(struct ospf6_prefix +				 *)((caddr_t)intra_prefix_lsa +				    + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE), +			lsalen - OSPF6_LSA_HEADER_SIZE +				- OSPF6_INTRA_PREFIX_LSA_MIN_SIZE, +			ntohs(intra_prefix_lsa->prefix_num) /* 16 bits */ +			); +	} +	/* No additional validation is possible for unknown LSA types, which are +	   themselves valid in OPSFv3, hence the default decision is to accept. +	   */ +	return MSG_OK;  }  /* Verify if the provided input buffer is a valid sequence of LSAs. This     includes verification of LSA blocks length/alignment and dispatching     of deeper-level checks. */  static unsigned -ospf6_lsaseq_examin -( -  struct ospf6_lsa_header *lsah, /* start of buffered data */ -  size_t length, -  const u_char headeronly, -  /* When declared_num_lsas is not 0, compare it to the real number of LSAs -     and treat the difference as an error. */ -  const u_int32_t declared_num_lsas -) +ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */ +		    size_t length, const u_char headeronly, +		    /* When declared_num_lsas is not 0, compare it to the real +		       number of LSAs +		       and treat the difference as an error. */ +		    const u_int32_t declared_num_lsas)  { -  u_int32_t counted_lsas = 0; - -  while (length) -  { -    u_int16_t lsalen; -    if (length < OSPF6_LSA_HEADER_SIZE) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header", -                    __func__, length, counted_lsas); -      return MSG_NG; -    } -    /* save on ntohs() calls here and in the LSA validator */ -    lsalen = OSPF6_LSA_SIZE (lsah); -    if (lsalen < OSPF6_LSA_HEADER_SIZE) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: malformed LSA header #%u, declared length is %u B", -                    __func__, counted_lsas, lsalen); -      return MSG_NG; -    } -    if (headeronly) -    { -      /* less checks here and in ospf6_lsa_examin() */ -      if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 1)) -      { -        if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -          zlog_debug ("%s: anomaly in header-only %s LSA #%u", __func__, -                      ospf6_lstype_name (lsah->type), counted_lsas); -        return MSG_NG; -      } -      lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); -      length -= OSPF6_LSA_HEADER_SIZE; -    } -    else -    { -      /* make sure the input buffer is deep enough before further checks */ -      if (lsalen > length) -      { -        if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -          zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B", -                      __func__, ospf6_lstype_name (lsah->type), counted_lsas, lsalen, length); -        return MSG_NG; -      } -      if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 0)) -      { -        if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -          zlog_debug ("%s: anomaly in %s LSA #%u", __func__, -                      ospf6_lstype_name (lsah->type), counted_lsas); -        return MSG_NG; -      } -      lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + lsalen); -      length -= lsalen; -    } -    counted_lsas++; -  } - -  if (declared_num_lsas && counted_lsas != declared_num_lsas) -  { -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)", -                  __func__, declared_num_lsas, counted_lsas); -    return MSG_NG; -  } -  return MSG_OK; +	u_int32_t counted_lsas = 0; + +	while (length) { +		u_int16_t lsalen; +		if (length < OSPF6_LSA_HEADER_SIZE) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug( +					"%s: undersized (%zu B) trailing (#%u) LSA header", +					__func__, length, counted_lsas); +			return MSG_NG; +		} +		/* save on ntohs() calls here and in the LSA validator */ +		lsalen = OSPF6_LSA_SIZE(lsah); +		if (lsalen < OSPF6_LSA_HEADER_SIZE) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, +						   RECV)) +				zlog_debug( +					"%s: malformed LSA header #%u, declared length is %u B", +					__func__, counted_lsas, lsalen); +			return MSG_NG; +		} +		if (headeronly) { +			/* less checks here and in ospf6_lsa_examin() */ +			if (MSG_OK != ospf6_lsa_examin(lsah, lsalen, 1)) { +				if (IS_OSPF6_DEBUG_MESSAGE( +					    OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +					zlog_debug( +						"%s: anomaly in header-only %s LSA #%u", +						__func__, +						ospf6_lstype_name(lsah->type), +						counted_lsas); +				return MSG_NG; +			} +			lsah = (struct ospf6_lsa_header +					*)((caddr_t)lsah +					   + OSPF6_LSA_HEADER_SIZE); +			length -= OSPF6_LSA_HEADER_SIZE; +		} else { +			/* make sure the input buffer is deep enough before +			 * further checks */ +			if (lsalen > length) { +				if (IS_OSPF6_DEBUG_MESSAGE( +					    OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +					zlog_debug( +						"%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B", +						__func__, +						ospf6_lstype_name(lsah->type), +						counted_lsas, lsalen, length); +				return MSG_NG; +			} +			if (MSG_OK != ospf6_lsa_examin(lsah, lsalen, 0)) { +				if (IS_OSPF6_DEBUG_MESSAGE( +					    OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +					zlog_debug( +						"%s: anomaly in %s LSA #%u", +						__func__, +						ospf6_lstype_name(lsah->type), +						counted_lsas); +				return MSG_NG; +			} +			lsah = (struct ospf6_lsa_header *)((caddr_t)lsah +							   + lsalen); +			length -= lsalen; +		} +		counted_lsas++; +	} + +	if (declared_num_lsas && counted_lsas != declared_num_lsas) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug( +				"%s: #LSAs declared (%u) does not match actual (%u)", +				__func__, declared_num_lsas, counted_lsas); +		return MSG_NG; +	} +	return MSG_OK;  }  /* Verify a complete OSPF packet for proper sizing/alignment. */ -static unsigned -ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire) +static unsigned ospf6_packet_examin(struct ospf6_header *oh, +				    const unsigned bytesonwire)  { -  struct ospf6_lsupdate *lsupd; -  unsigned test; - -  /* length, 1st approximation */ -  if (bytesonwire < OSPF6_HEADER_SIZE) -  { -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire); -    return MSG_NG; -  } -  /* Now it is safe to access header fields. */ -  if (bytesonwire != ntohs (oh->length)) -  { -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: packet length error (%u real, %u declared)", -                  __func__, bytesonwire, ntohs (oh->length)); -    return MSG_NG; -  } -  /* version check */ -  if (oh->version != OSPFV3_VERSION) -  { -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version); -    return MSG_NG; -  } -  /* length, 2nd approximation */ -  if -  ( -    oh->type < OSPF6_MESSAGE_TYPE_ALL && -    ospf6_packet_minlen[oh->type] && -    bytesonwire < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type] -  ) -  { -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: undersized (%u B) %s packet", __func__, -                  bytesonwire, lookup_msg(ospf6_message_type_str, oh->type, NULL)); -    return MSG_NG; -  } -  /* type-specific deeper validation */ -  switch (oh->type) -  { -  case OSPF6_MESSAGE_TYPE_HELLO: -    /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes followed -       by N>=0 router-IDs. */ -    if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE) % 4) -      return MSG_OK; -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: alignment error in %s packet", -                  __func__, lookup_msg(ospf6_message_type_str, oh->type, NULL)); -    return MSG_NG; -  case OSPF6_MESSAGE_TYPE_DBDESC: -    /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes followed -       by N>=0 header-only LSAs. */ -    test = ospf6_lsaseq_examin -    ( -      (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_DB_DESC_MIN_SIZE), -      bytesonwire - OSPF6_HEADER_SIZE - OSPF6_DB_DESC_MIN_SIZE, -      1, -      0 -    ); -    break; -  case OSPF6_MESSAGE_TYPE_LSREQ: -    /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */ -    if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE) % OSPF6_LSREQ_LSDESC_FIX_SIZE) -      return MSG_OK; -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: alignment error in %s packet", -                  __func__, lookup_msg(ospf6_message_type_str, oh->type, NULL)); -    return MSG_NG; -  case OSPF6_MESSAGE_TYPE_LSUPDATE: -    /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes followed -       by N>=0 full LSAs (with N declared beforehand). */ -    lsupd = (struct ospf6_lsupdate *) ((caddr_t) oh + OSPF6_HEADER_SIZE); -    test = ospf6_lsaseq_examin -    ( -      (struct ospf6_lsa_header *) ((caddr_t) lsupd + OSPF6_LS_UPD_MIN_SIZE), -      bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE, -      0, -      ntohl (lsupd->lsa_number) /* 32 bits */ -    ); -    break; -  case OSPF6_MESSAGE_TYPE_LSACK: -    /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */ -    test = ospf6_lsaseq_examin -    ( -      (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_LS_ACK_MIN_SIZE), -      bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE, -      1, -      0 -    ); -    break; -  default: -    if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -      zlog_debug ("%s: invalid (%u) message type", __func__, oh->type); -    return MSG_NG; -  } -  if (test != MSG_OK && IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -    zlog_debug ("%s: anomaly in %s packet", __func__, lookup_msg(ospf6_message_type_str, oh->type, NULL)); -  return test; +	struct ospf6_lsupdate *lsupd; +	unsigned test; + +	/* length, 1st approximation */ +	if (bytesonwire < OSPF6_HEADER_SIZE) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug("%s: undersized (%u B) packet", __func__, +				   bytesonwire); +		return MSG_NG; +	} +	/* Now it is safe to access header fields. */ +	if (bytesonwire != ntohs(oh->length)) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug( +				"%s: packet length error (%u real, %u declared)", +				__func__, bytesonwire, ntohs(oh->length)); +		return MSG_NG; +	} +	/* version check */ +	if (oh->version != OSPFV3_VERSION) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug("%s: invalid (%u) protocol version", +				   __func__, oh->version); +		return MSG_NG; +	} +	/* length, 2nd approximation */ +	if (oh->type < OSPF6_MESSAGE_TYPE_ALL && ospf6_packet_minlen[oh->type] +	    && bytesonwire +		       < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type]) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug("%s: undersized (%u B) %s packet", __func__, +				   bytesonwire, +				   lookup_msg(ospf6_message_type_str, oh->type, +					      NULL)); +		return MSG_NG; +	} +	/* type-specific deeper validation */ +	switch (oh->type) { +	case OSPF6_MESSAGE_TYPE_HELLO: +		/* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes +		   followed +		   by N>=0 router-IDs. */ +		if (0 +		    == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE) +			       % 4) +			return MSG_OK; +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug("%s: alignment error in %s packet", __func__, +				   lookup_msg(ospf6_message_type_str, oh->type, +					      NULL)); +		return MSG_NG; +	case OSPF6_MESSAGE_TYPE_DBDESC: +		/* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes +		   followed +		   by N>=0 header-only LSAs. */ +		test = ospf6_lsaseq_examin( +			(struct ospf6_lsa_header *)((caddr_t)oh +						    + OSPF6_HEADER_SIZE +						    + OSPF6_DB_DESC_MIN_SIZE), +			bytesonwire - OSPF6_HEADER_SIZE +				- OSPF6_DB_DESC_MIN_SIZE, +			1, 0); +		break; +	case OSPF6_MESSAGE_TYPE_LSREQ: +		/* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */ +		if (0 +		    == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE) +			       % OSPF6_LSREQ_LSDESC_FIX_SIZE) +			return MSG_OK; +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug("%s: alignment error in %s packet", __func__, +				   lookup_msg(ospf6_message_type_str, oh->type, +					      NULL)); +		return MSG_NG; +	case OSPF6_MESSAGE_TYPE_LSUPDATE: +		/* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes +		   followed +		   by N>=0 full LSAs (with N declared beforehand). */ +		lsupd = (struct ospf6_lsupdate *)((caddr_t)oh +						  + OSPF6_HEADER_SIZE); +		test = ospf6_lsaseq_examin( +			(struct ospf6_lsa_header *)((caddr_t)lsupd +						    + OSPF6_LS_UPD_MIN_SIZE), +			bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE, +			0, ntohl(lsupd->lsa_number) /* 32 bits */ +			); +		break; +	case OSPF6_MESSAGE_TYPE_LSACK: +		/* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */ +		test = ospf6_lsaseq_examin( +			(struct ospf6_lsa_header *)((caddr_t)oh +						    + OSPF6_HEADER_SIZE +						    + OSPF6_LS_ACK_MIN_SIZE), +			bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE, +			1, 0); +		break; +	default: +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug("%s: invalid (%u) message type", __func__, +				   oh->type); +		return MSG_NG; +	} +	if (test != MSG_OK +	    && IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +		zlog_debug("%s: anomaly in %s packet", __func__, +			   lookup_msg(ospf6_message_type_str, oh->type, NULL)); +	return test;  }  /* Verify particular fields of otherwise correct received OSPF packet to     meet the requirements of RFC. */ -static int -ospf6_rxpacket_examin (struct ospf6_interface *oi, struct ospf6_header *oh, const unsigned bytesonwire) +static int ospf6_rxpacket_examin(struct ospf6_interface *oi, +				 struct ospf6_header *oh, +				 const unsigned bytesonwire)  { -  char buf[2][INET_ADDRSTRLEN]; - -  if (MSG_OK != ospf6_packet_examin (oh, bytesonwire)) -    return MSG_NG; - -  /* Area-ID check */ -  if (oh->area_id != oi->area->area_id) -  { -    if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -    { -      if (oh->area_id == OSPF_AREA_BACKBONE) -        zlog_debug ("%s: Message may be via Virtual Link: not supported", __func__); -      else -        zlog_debug -        ( -          "%s: Area-ID mismatch (my %s, rcvd %s)", __func__, -          inet_ntop (AF_INET, &oi->area->area_id, buf[0], INET_ADDRSTRLEN), -          inet_ntop (AF_INET, &oh->area_id, buf[1], INET_ADDRSTRLEN) -         ); -    } -    return MSG_NG; -  } - -  /* Instance-ID check */ -  if (oh->instance_id != oi->instance_id) -  { -    if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -      zlog_debug ("%s: Instance-ID mismatch (my %u, rcvd %u)", __func__, oi->instance_id, oh->instance_id); -    return MSG_NG; -  } - -  /* Router-ID check */ -  if (oh->router_id == oi->area->ospf6->router_id) -  { -    zlog_warn ("%s: Duplicate Router-ID (%s)", __func__, inet_ntop (AF_INET, &oh->router_id, buf[0], INET_ADDRSTRLEN)); -    return MSG_NG; -  } -  return MSG_OK; +	char buf[2][INET_ADDRSTRLEN]; + +	if (MSG_OK != ospf6_packet_examin(oh, bytesonwire)) +		return MSG_NG; + +	/* Area-ID check */ +	if (oh->area_id != oi->area->area_id) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) { +			if (oh->area_id == OSPF_AREA_BACKBONE) +				zlog_debug( +					"%s: Message may be via Virtual Link: not supported", +					__func__); +			else +				zlog_debug( +					"%s: Area-ID mismatch (my %s, rcvd %s)", +					__func__, +					inet_ntop(AF_INET, &oi->area->area_id, +						  buf[0], INET_ADDRSTRLEN), +					inet_ntop(AF_INET, &oh->area_id, buf[1], +						  INET_ADDRSTRLEN)); +		} +		return MSG_NG; +	} + +	/* Instance-ID check */ +	if (oh->instance_id != oi->instance_id) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("%s: Instance-ID mismatch (my %u, rcvd %u)", +				   __func__, oi->instance_id, oh->instance_id); +		return MSG_NG; +	} + +	/* Router-ID check */ +	if (oh->router_id == oi->area->ospf6->router_id) { +		zlog_warn("%s: Duplicate Router-ID (%s)", __func__, +			  inet_ntop(AF_INET, &oh->router_id, buf[0], +				    INET_ADDRSTRLEN)); +		return MSG_NG; +	} +	return MSG_OK;  } -static void -ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst, -                     struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_lsupdate_recv(struct in6_addr *src, struct in6_addr *dst, +				struct ospf6_interface *oi, +				struct ospf6_header *oh)  { -  struct ospf6_neighbor *on; -  struct ospf6_lsupdate *lsupdate; -  char *p; - -  on = ospf6_neighbor_lookup (oh->router_id, oi); -  if (on == NULL) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor not found, ignore"); -      return; -    } - -  if (on->state != OSPF6_NEIGHBOR_EXCHANGE && -      on->state != OSPF6_NEIGHBOR_LOADING && -      on->state != OSPF6_NEIGHBOR_FULL) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor state less than Exchange, ignore"); -      return; -    } - -  lsupdate = (struct ospf6_lsupdate *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); - -  /* Process LSAs */ -  for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); -       p < OSPF6_MESSAGE_END (oh) && -       p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh); -       p += OSPF6_LSA_SIZE (p)) -    { -      ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p); -    } - -  assert (p == OSPF6_MESSAGE_END (oh)); +	struct ospf6_neighbor *on; +	struct ospf6_lsupdate *lsupdate; +	char *p; + +	on = ospf6_neighbor_lookup(oh->router_id, oi); +	if (on == NULL) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor not found, ignore"); +		return; +	} + +	if (on->state != OSPF6_NEIGHBOR_EXCHANGE +	    && on->state != OSPF6_NEIGHBOR_LOADING +	    && on->state != OSPF6_NEIGHBOR_FULL) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor state less than Exchange, ignore"); +		return; +	} + +	lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh +					     + sizeof(struct ospf6_header)); +	/* Process LSAs */ +	for (p = (char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); +	     p < OSPF6_MESSAGE_END(oh) +	     && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh); +	     p += OSPF6_LSA_SIZE(p)) { +		ospf6_receive_lsa(on, (struct ospf6_lsa_header *)p); +	} + +	assert(p == OSPF6_MESSAGE_END(oh));  } -static void -ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst, -                  struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_lsack_recv(struct in6_addr *src, struct in6_addr *dst, +			     struct ospf6_interface *oi, +			     struct ospf6_header *oh)  { -  struct ospf6_neighbor *on; -  char *p; -  struct ospf6_lsa *his, *mine; -  struct ospf6_lsdb *lsdb = NULL; - -  assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK); - -  on = ospf6_neighbor_lookup (oh->router_id, oi); -  if (on == NULL) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor not found, ignore"); -      return; -    } - -  if (on->state != OSPF6_NEIGHBOR_EXCHANGE && -      on->state != OSPF6_NEIGHBOR_LOADING && -      on->state != OSPF6_NEIGHBOR_FULL) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Neighbor state less than Exchange, ignore"); -      return; -    } - -  for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); -       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); -       p += sizeof (struct ospf6_lsa_header)) -    { -      his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p); - -      switch (OSPF6_LSA_SCOPE (his->header->type)) -        { -        case OSPF6_SCOPE_LINKLOCAL: -          lsdb = on->ospf6_if->lsdb; -          break; -        case OSPF6_SCOPE_AREA: -          lsdb = on->ospf6_if->area->lsdb; -          break; -        case OSPF6_SCOPE_AS: -          lsdb = on->ospf6_if->area->ospf6->lsdb; -          break; -        case OSPF6_SCOPE_RESERVED: -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Ignoring LSA of reserved scope"); -          ospf6_lsa_delete (his); -          continue; -          break; -        } - -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("%s acknowledged by %s", his->name, on->name); - -      /* Find database copy */ -      mine = ospf6_lsdb_lookup (his->header->type, his->header->id, -                                his->header->adv_router, lsdb); -      if (mine == NULL) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("No database copy"); -          ospf6_lsa_delete (his); -          continue; -        } - -      /* Check if the LSA is on his retrans-list */ -      mine = ospf6_lsdb_lookup (his->header->type, his->header->id, -                                his->header->adv_router, on->retrans_list); -      if (mine == NULL) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Not on %s's retrans-list", on->name); -          ospf6_lsa_delete (his); -          continue; -        } - -      if (ospf6_lsa_compare (his, mine) != 0) -        { -          /* Log this questionable acknowledgement, -             and examine the next one. */ -          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -            zlog_debug ("Questionable acknowledgement"); -          ospf6_lsa_delete (his); -          continue; -        } - -      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -        zlog_debug ("Acknowledged, remove from %s's retrans-list", -		    on->name); - -      ospf6_decrement_retrans_count (mine); -      if (OSPF6_LSA_IS_MAXAGE (mine)) -        ospf6_maxage_remove (on->ospf6_if->area->ospf6); -      ospf6_lsdb_remove (mine, on->retrans_list); -      ospf6_lsa_delete (his); -    } - -  assert (p == OSPF6_MESSAGE_END (oh)); +	struct ospf6_neighbor *on; +	char *p; +	struct ospf6_lsa *his, *mine; +	struct ospf6_lsdb *lsdb = NULL; + +	assert(oh->type == OSPF6_MESSAGE_TYPE_LSACK); + +	on = ospf6_neighbor_lookup(oh->router_id, oi); +	if (on == NULL) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor not found, ignore"); +		return; +	} + +	if (on->state != OSPF6_NEIGHBOR_EXCHANGE +	    && on->state != OSPF6_NEIGHBOR_LOADING +	    && on->state != OSPF6_NEIGHBOR_FULL) { +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("Neighbor state less than Exchange, ignore"); +		return; +	} + +	for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header)); +	     p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); +	     p += sizeof(struct ospf6_lsa_header)) { +		his = ospf6_lsa_create_headeronly((struct ospf6_lsa_header *)p); + +		switch (OSPF6_LSA_SCOPE(his->header->type)) { +		case OSPF6_SCOPE_LINKLOCAL: +			lsdb = on->ospf6_if->lsdb; +			break; +		case OSPF6_SCOPE_AREA: +			lsdb = on->ospf6_if->area->lsdb; +			break; +		case OSPF6_SCOPE_AS: +			lsdb = on->ospf6_if->area->ospf6->lsdb; +			break; +		case OSPF6_SCOPE_RESERVED: +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Ignoring LSA of reserved scope"); +			ospf6_lsa_delete(his); +			continue; +			break; +		} + +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug("%s acknowledged by %s", his->name, +				   on->name); + +		/* Find database copy */ +		mine = ospf6_lsdb_lookup(his->header->type, his->header->id, +					 his->header->adv_router, lsdb); +		if (mine == NULL) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("No database copy"); +			ospf6_lsa_delete(his); +			continue; +		} + +		/* Check if the LSA is on his retrans-list */ +		mine = ospf6_lsdb_lookup(his->header->type, his->header->id, +					 his->header->adv_router, +					 on->retrans_list); +		if (mine == NULL) { +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Not on %s's retrans-list", +					   on->name); +			ospf6_lsa_delete(his); +			continue; +		} + +		if (ospf6_lsa_compare(his, mine) != 0) { +			/* Log this questionable acknowledgement, +			   and examine the next one. */ +			if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +				zlog_debug("Questionable acknowledgement"); +			ospf6_lsa_delete(his); +			continue; +		} + +		if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) +			zlog_debug( +				"Acknowledged, remove from %s's retrans-list", +				on->name); + +		ospf6_decrement_retrans_count(mine); +		if (OSPF6_LSA_IS_MAXAGE(mine)) +			ospf6_maxage_remove(on->ospf6_if->area->ospf6); +		ospf6_lsdb_remove(mine, on->retrans_list); +		ospf6_lsa_delete(his); +	} + +	assert(p == OSPF6_MESSAGE_END(oh));  }  static u_char *recvbuf = NULL;  static u_char *sendbuf = NULL;  static unsigned int iobuflen = 0; -int -ospf6_iobuf_size (unsigned int size) +int ospf6_iobuf_size(unsigned int size)  { -  u_char *recvnew, *sendnew; - -  if (size <= iobuflen) -    return iobuflen; - -  recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size); -  sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size); -  if (recvnew == NULL || sendnew == NULL) -    { -      if (recvnew) -        XFREE (MTYPE_OSPF6_MESSAGE, recvnew); -      if (sendnew) -        XFREE (MTYPE_OSPF6_MESSAGE, sendnew); -      zlog_debug ("Could not allocate I/O buffer of size %d.", size); -      return iobuflen; -    } - -  if (recvbuf) -    XFREE (MTYPE_OSPF6_MESSAGE, recvbuf); -  if (sendbuf) -    XFREE (MTYPE_OSPF6_MESSAGE, sendbuf); -  recvbuf = recvnew; -  sendbuf = sendnew; -  iobuflen = size; - -  return iobuflen; +	u_char *recvnew, *sendnew; + +	if (size <= iobuflen) +		return iobuflen; + +	recvnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size); +	sendnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size); +	if (recvnew == NULL || sendnew == NULL) { +		if (recvnew) +			XFREE(MTYPE_OSPF6_MESSAGE, recvnew); +		if (sendnew) +			XFREE(MTYPE_OSPF6_MESSAGE, sendnew); +		zlog_debug("Could not allocate I/O buffer of size %d.", size); +		return iobuflen; +	} + +	if (recvbuf) +		XFREE(MTYPE_OSPF6_MESSAGE, recvbuf); +	if (sendbuf) +		XFREE(MTYPE_OSPF6_MESSAGE, sendbuf); +	recvbuf = recvnew; +	sendbuf = sendnew; +	iobuflen = size; + +	return iobuflen;  } -void -ospf6_message_terminate (void) +void ospf6_message_terminate(void)  { -  if (recvbuf) -    { -      XFREE (MTYPE_OSPF6_MESSAGE, recvbuf); -      recvbuf = NULL; -    } - -  if (sendbuf) -    { -      XFREE (MTYPE_OSPF6_MESSAGE, sendbuf); -      sendbuf = NULL; -    } - -  iobuflen = 0; +	if (recvbuf) { +		XFREE(MTYPE_OSPF6_MESSAGE, recvbuf); +		recvbuf = NULL; +	} + +	if (sendbuf) { +		XFREE(MTYPE_OSPF6_MESSAGE, sendbuf); +		sendbuf = NULL; +	} + +	iobuflen = 0;  } -int -ospf6_receive (struct thread *thread) +int ospf6_receive(struct thread *thread)  { -  int sockfd; -  unsigned int len; -  char srcname[64], dstname[64]; -  struct in6_addr src, dst; -  ifindex_t ifindex; -  struct iovec iovector[2]; -  struct ospf6_interface *oi; -  struct ospf6_header *oh; - -  /* add next read thread */ -  sockfd = THREAD_FD (thread); -  thread_add_read (master, ospf6_receive, NULL, sockfd, NULL); - -  /* initialize */ -  memset (&src, 0, sizeof (src)); -  memset (&dst, 0, sizeof (dst)); -  ifindex = 0; -  memset (recvbuf, 0, iobuflen); -  iovector[0].iov_base = recvbuf; -  iovector[0].iov_len = iobuflen; -  iovector[1].iov_base = NULL; -  iovector[1].iov_len = 0; - -  /* receive message */ -  len = ospf6_recvmsg (&src, &dst, &ifindex, iovector); -  if (len > iobuflen) -    { -      zlog_err ("Excess message read"); -      return 0; -    } - -  oi = ospf6_interface_lookup_by_ifindex (ifindex); -  if (oi == NULL || oi->area == NULL || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) -    { -      zlog_debug ("Message received on disabled interface"); -      return 0; -    } -  if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE)) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -        zlog_debug ("%s: Ignore message on passive interface %s", -                    __func__, oi->interface->name); -      return 0; -    } - -  oh = (struct ospf6_header *) recvbuf; -  if (ospf6_rxpacket_examin (oi, oh, len) != MSG_OK) -    return 0; - -  /* Being here means, that no sizing/alignment issues were detected in -     the input packet. This renders the additional checks performed below -     and also in the type-specific dispatching functions a dead code, -     which can be dismissed in a cleanup-focused review round later. */ - -  /* Log */ -  if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) -    { -      inet_ntop (AF_INET6, &src, srcname, sizeof (srcname)); -      inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname)); -      zlog_debug ("%s received on %s", -                 lookup_msg(ospf6_message_type_str, oh->type, NULL), oi->interface->name); -      zlog_debug ("    src: %s", srcname); -      zlog_debug ("    dst: %s", dstname); - -      switch (oh->type) -        { -          case OSPF6_MESSAGE_TYPE_HELLO: -            ospf6_hello_print (oh); -            break; -          case OSPF6_MESSAGE_TYPE_DBDESC: -            ospf6_dbdesc_print (oh); -            break; -          case OSPF6_MESSAGE_TYPE_LSREQ: -            ospf6_lsreq_print (oh); -            break; -          case OSPF6_MESSAGE_TYPE_LSUPDATE: -            ospf6_lsupdate_print (oh); -            break; -          case OSPF6_MESSAGE_TYPE_LSACK: -            ospf6_lsack_print (oh); -            break; -          default: -            assert (0); -        } -    } - -  switch (oh->type) -    { -      case OSPF6_MESSAGE_TYPE_HELLO: -        ospf6_hello_recv (&src, &dst, oi, oh); -        break; - -      case OSPF6_MESSAGE_TYPE_DBDESC: -        ospf6_dbdesc_recv (&src, &dst, oi, oh); -        break; - -      case OSPF6_MESSAGE_TYPE_LSREQ: -        ospf6_lsreq_recv (&src, &dst, oi, oh); -        break; - -      case OSPF6_MESSAGE_TYPE_LSUPDATE: -        ospf6_lsupdate_recv (&src, &dst, oi, oh); -        break; - -      case OSPF6_MESSAGE_TYPE_LSACK: -        ospf6_lsack_recv (&src, &dst, oi, oh); -        break; - -      default: -        assert (0); -    } - -  return 0; +	int sockfd; +	unsigned int len; +	char srcname[64], dstname[64]; +	struct in6_addr src, dst; +	ifindex_t ifindex; +	struct iovec iovector[2]; +	struct ospf6_interface *oi; +	struct ospf6_header *oh; + +	/* add next read thread */ +	sockfd = THREAD_FD(thread); +	thread_add_read(master, ospf6_receive, NULL, sockfd, NULL); + +	/* initialize */ +	memset(&src, 0, sizeof(src)); +	memset(&dst, 0, sizeof(dst)); +	ifindex = 0; +	memset(recvbuf, 0, iobuflen); +	iovector[0].iov_base = recvbuf; +	iovector[0].iov_len = iobuflen; +	iovector[1].iov_base = NULL; +	iovector[1].iov_len = 0; + +	/* receive message */ +	len = ospf6_recvmsg(&src, &dst, &ifindex, iovector); +	if (len > iobuflen) { +		zlog_err("Excess message read"); +		return 0; +	} + +	oi = ospf6_interface_lookup_by_ifindex(ifindex); +	if (oi == NULL || oi->area == NULL +	    || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) { +		zlog_debug("Message received on disabled interface"); +		return 0; +	} +	if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +			zlog_debug("%s: Ignore message on passive interface %s", +				   __func__, oi->interface->name); +		return 0; +	} + +	oh = (struct ospf6_header *)recvbuf; +	if (ospf6_rxpacket_examin(oi, oh, len) != MSG_OK) +		return 0; + +	/* Being here means, that no sizing/alignment issues were detected in +	   the input packet. This renders the additional checks performed below +	   and also in the type-specific dispatching functions a dead code, +	   which can be dismissed in a cleanup-focused review round later. */ + +	/* Log */ +	if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) { +		inet_ntop(AF_INET6, &src, srcname, sizeof(srcname)); +		inet_ntop(AF_INET6, &dst, dstname, sizeof(dstname)); +		zlog_debug("%s received on %s", +			   lookup_msg(ospf6_message_type_str, oh->type, NULL), +			   oi->interface->name); +		zlog_debug("    src: %s", srcname); +		zlog_debug("    dst: %s", dstname); + +		switch (oh->type) { +		case OSPF6_MESSAGE_TYPE_HELLO: +			ospf6_hello_print(oh); +			break; +		case OSPF6_MESSAGE_TYPE_DBDESC: +			ospf6_dbdesc_print(oh); +			break; +		case OSPF6_MESSAGE_TYPE_LSREQ: +			ospf6_lsreq_print(oh); +			break; +		case OSPF6_MESSAGE_TYPE_LSUPDATE: +			ospf6_lsupdate_print(oh); +			break; +		case OSPF6_MESSAGE_TYPE_LSACK: +			ospf6_lsack_print(oh); +			break; +		default: +			assert(0); +		} +	} + +	switch (oh->type) { +	case OSPF6_MESSAGE_TYPE_HELLO: +		ospf6_hello_recv(&src, &dst, oi, oh); +		break; + +	case OSPF6_MESSAGE_TYPE_DBDESC: +		ospf6_dbdesc_recv(&src, &dst, oi, oh); +		break; + +	case OSPF6_MESSAGE_TYPE_LSREQ: +		ospf6_lsreq_recv(&src, &dst, oi, oh); +		break; + +	case OSPF6_MESSAGE_TYPE_LSUPDATE: +		ospf6_lsupdate_recv(&src, &dst, oi, oh); +		break; + +	case OSPF6_MESSAGE_TYPE_LSACK: +		ospf6_lsack_recv(&src, &dst, oi, oh); +		break; + +	default: +		assert(0); +	} + +	return 0;  } -static void -ospf6_send (struct in6_addr *src, struct in6_addr *dst, -            struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_send(struct in6_addr *src, struct in6_addr *dst, +		       struct ospf6_interface *oi, struct ospf6_header *oh)  { -  unsigned int len; -  char srcname[64], dstname[64]; -  struct iovec iovector[2]; - -  /* initialize */ -  iovector[0].iov_base = (caddr_t) oh; -  iovector[0].iov_len = ntohs (oh->length); -  iovector[1].iov_base = NULL; -  iovector[1].iov_len = 0; - -  /* fill OSPF header */ -  oh->version = OSPFV3_VERSION; -  /* message type must be set before */ -  /* message length must be set before */ -  oh->router_id = oi->area->ospf6->router_id; -  oh->area_id = oi->area->area_id; -  /* checksum is calculated by kernel */ -  oh->instance_id = oi->instance_id; -  oh->reserved = 0; - -  /* Log */ -  if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND)) -    { -      inet_ntop (AF_INET6, dst, dstname, sizeof (dstname)); -      if (src) -        inet_ntop (AF_INET6, src, srcname, sizeof (srcname)); -      else -        memset (srcname, 0, sizeof (srcname)); -      zlog_debug ("%s send on %s", -                 lookup_msg(ospf6_message_type_str, oh->type, NULL), oi->interface->name); -      zlog_debug ("    src: %s", srcname); -      zlog_debug ("    dst: %s", dstname); - -      switch (oh->type) -        { -          case OSPF6_MESSAGE_TYPE_HELLO: -            ospf6_hello_print (oh); -            break; -          case OSPF6_MESSAGE_TYPE_DBDESC: -            ospf6_dbdesc_print (oh); -            break; -          case OSPF6_MESSAGE_TYPE_LSREQ: -            ospf6_lsreq_print (oh); -            break; -          case OSPF6_MESSAGE_TYPE_LSUPDATE: -            ospf6_lsupdate_print (oh); -            break; -          case OSPF6_MESSAGE_TYPE_LSACK: -            ospf6_lsack_print (oh); -            break; -          default: -            zlog_debug ("Unknown message"); -            assert (0); -            break; -        } -    } - -  /* send message */ -  len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector); -  if (len != ntohs (oh->length)) -    zlog_err ("Could not send entire message"); +	unsigned int len; +	char srcname[64], dstname[64]; +	struct iovec iovector[2]; + +	/* initialize */ +	iovector[0].iov_base = (caddr_t)oh; +	iovector[0].iov_len = ntohs(oh->length); +	iovector[1].iov_base = NULL; +	iovector[1].iov_len = 0; + +	/* fill OSPF header */ +	oh->version = OSPFV3_VERSION; +	/* message type must be set before */ +	/* message length must be set before */ +	oh->router_id = oi->area->ospf6->router_id; +	oh->area_id = oi->area->area_id; +	/* checksum is calculated by kernel */ +	oh->instance_id = oi->instance_id; +	oh->reserved = 0; + +	/* Log */ +	if (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)) { +		inet_ntop(AF_INET6, dst, dstname, sizeof(dstname)); +		if (src) +			inet_ntop(AF_INET6, src, srcname, sizeof(srcname)); +		else +			memset(srcname, 0, sizeof(srcname)); +		zlog_debug("%s send on %s", +			   lookup_msg(ospf6_message_type_str, oh->type, NULL), +			   oi->interface->name); +		zlog_debug("    src: %s", srcname); +		zlog_debug("    dst: %s", dstname); + +		switch (oh->type) { +		case OSPF6_MESSAGE_TYPE_HELLO: +			ospf6_hello_print(oh); +			break; +		case OSPF6_MESSAGE_TYPE_DBDESC: +			ospf6_dbdesc_print(oh); +			break; +		case OSPF6_MESSAGE_TYPE_LSREQ: +			ospf6_lsreq_print(oh); +			break; +		case OSPF6_MESSAGE_TYPE_LSUPDATE: +			ospf6_lsupdate_print(oh); +			break; +		case OSPF6_MESSAGE_TYPE_LSACK: +			ospf6_lsack_print(oh); +			break; +		default: +			zlog_debug("Unknown message"); +			assert(0); +			break; +		} +	} + +	/* send message */ +	len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector); +	if (len != ntohs(oh->length)) +		zlog_err("Could not send entire message");  } -static uint32_t -ospf6_packet_max(struct ospf6_interface *oi) +static uint32_t ospf6_packet_max(struct ospf6_interface *oi)  { -  assert (oi->ifmtu > sizeof (struct ip6_hdr)); -  return oi->ifmtu - (sizeof (struct ip6_hdr)); +	assert(oi->ifmtu > sizeof(struct ip6_hdr)); +	return oi->ifmtu - (sizeof(struct ip6_hdr));  } -int -ospf6_hello_send (struct thread *thread) +int ospf6_hello_send(struct thread *thread)  { -  struct ospf6_interface *oi; -  struct ospf6_header *oh; -  struct ospf6_hello *hello; -  u_char *p; -  struct listnode *node, *nnode; -  struct ospf6_neighbor *on; - -  oi = (struct ospf6_interface *) THREAD_ARG (thread); -  oi->thread_send_hello = (struct thread *) NULL; - -  if (oi->state <= OSPF6_INTERFACE_DOWN) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND)) -        zlog_debug ("Unable to send Hello on down interface %s", -                   oi->interface->name); -      return 0; -    } - -  if (iobuflen == 0) -    { -      zlog_debug ("Unable to send Hello on interface %s iobuflen is 0", -                 oi->interface->name); -      return 0; -    } - -  /* set next thread */ -  thread_add_timer (master, ospf6_hello_send, oi, oi->hello_interval, &oi->thread_send_hello); - -  memset (sendbuf, 0, iobuflen); -  oh = (struct ospf6_header *) sendbuf; -  hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header)); - -  hello->interface_id = htonl (oi->interface->ifindex); -  hello->priority = oi->priority; -  hello->options[0] = oi->area->options[0]; -  hello->options[1] = oi->area->options[1]; -  hello->options[2] = oi->area->options[2]; -  hello->hello_interval = htons (oi->hello_interval); -  hello->dead_interval = htons (oi->dead_interval); -  hello->drouter = oi->drouter; -  hello->bdrouter = oi->bdrouter; - -  p = (u_char *)((caddr_t) hello + sizeof (struct ospf6_hello)); - -  for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) -    { -      if (on->state < OSPF6_NEIGHBOR_INIT) -        continue; - -      if (p - sendbuf + sizeof (u_int32_t) > ospf6_packet_max(oi)) -        { -          if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND)) -            zlog_debug ("sending Hello message: exceeds I/F MTU"); -          break; -        } - -      memcpy (p, &on->router_id, sizeof (u_int32_t)); -      p += sizeof (u_int32_t); -    } - -  oh->type = OSPF6_MESSAGE_TYPE_HELLO; -  oh->length = htons (p - sendbuf); - -  ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh); -  return 0; +	struct ospf6_interface *oi; +	struct ospf6_header *oh; +	struct ospf6_hello *hello; +	u_char *p; +	struct listnode *node, *nnode; +	struct ospf6_neighbor *on; + +	oi = (struct ospf6_interface *)THREAD_ARG(thread); +	oi->thread_send_hello = (struct thread *)NULL; + +	if (oi->state <= OSPF6_INTERFACE_DOWN) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, SEND)) +			zlog_debug("Unable to send Hello on down interface %s", +				   oi->interface->name); +		return 0; +	} + +	if (iobuflen == 0) { +		zlog_debug("Unable to send Hello on interface %s iobuflen is 0", +			   oi->interface->name); +		return 0; +	} + +	/* set next thread */ +	thread_add_timer(master, ospf6_hello_send, oi, oi->hello_interval, +			 &oi->thread_send_hello); + +	memset(sendbuf, 0, iobuflen); +	oh = (struct ospf6_header *)sendbuf; +	hello = (struct ospf6_hello *)((caddr_t)oh +				       + sizeof(struct ospf6_header)); + +	hello->interface_id = htonl(oi->interface->ifindex); +	hello->priority = oi->priority; +	hello->options[0] = oi->area->options[0]; +	hello->options[1] = oi->area->options[1]; +	hello->options[2] = oi->area->options[2]; +	hello->hello_interval = htons(oi->hello_interval); +	hello->dead_interval = htons(oi->dead_interval); +	hello->drouter = oi->drouter; +	hello->bdrouter = oi->bdrouter; + +	p = (u_char *)((caddr_t)hello + sizeof(struct ospf6_hello)); + +	for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) { +		if (on->state < OSPF6_NEIGHBOR_INIT) +			continue; + +		if (p - sendbuf + sizeof(u_int32_t) > ospf6_packet_max(oi)) { +			if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, +						   SEND)) +				zlog_debug( +					"sending Hello message: exceeds I/F MTU"); +			break; +		} + +		memcpy(p, &on->router_id, sizeof(u_int32_t)); +		p += sizeof(u_int32_t); +	} + +	oh->type = OSPF6_MESSAGE_TYPE_HELLO; +	oh->length = htons(p - sendbuf); + +	ospf6_send(oi->linklocal_addr, &allspfrouters6, oi, oh); +	return 0;  } -int -ospf6_dbdesc_send (struct thread *thread) +int ospf6_dbdesc_send(struct thread *thread)  { -  struct ospf6_neighbor *on; -  struct ospf6_header *oh; -  struct ospf6_dbdesc *dbdesc; -  u_char *p; -  struct ospf6_lsa *lsa; -  struct in6_addr *dst; - -  on = (struct ospf6_neighbor *) THREAD_ARG (thread); -  on->thread_send_dbdesc = (struct thread *) NULL; - -  if (on->state < OSPF6_NEIGHBOR_EXSTART) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND)) -        zlog_debug ("Quit to send DbDesc to neighbor %s state %s", -		    on->name, ospf6_neighbor_state_str[on->state]); -      return 0; -    } - -  /* set next thread if master */ -  if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT)) -    thread_add_timer (master, ospf6_dbdesc_send, on, -                      on->ospf6_if->rxmt_interval, -                      &on->thread_send_dbdesc); - -  memset (sendbuf, 0, iobuflen); -  oh = (struct ospf6_header *) sendbuf; -  dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh + -                                   sizeof (struct ospf6_header)); - -  /* if this is initial one, initialize sequence number for DbDesc */ -  if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) && -      (on->dbdesc_seqnum == 0)) -    { -      on->dbdesc_seqnum = monotime(NULL); -    } - -  dbdesc->options[0] = on->ospf6_if->area->options[0]; -  dbdesc->options[1] = on->ospf6_if->area->options[1]; -  dbdesc->options[2] = on->ospf6_if->area->options[2]; -  dbdesc->ifmtu = htons (on->ospf6_if->ifmtu); -  dbdesc->bits = on->dbdesc_bits; -  dbdesc->seqnum = htonl (on->dbdesc_seqnum); - -  /* if this is not initial one, set LSA headers in dbdesc */ -  p = (u_char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); -  if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT)) -    { -      for (ALL_LSDB(on->dbdesc_list, lsa)) -        { -          ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay); - -          /* MTU check */ -          if (p - sendbuf + sizeof (struct ospf6_lsa_header) > -              ospf6_packet_max(on->ospf6_if)) -            { -              ospf6_lsdb_lsa_unlock (lsa); -              break; -            } -          memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header)); -          p += sizeof (struct ospf6_lsa_header); -        } -    } - -  oh->type = OSPF6_MESSAGE_TYPE_DBDESC; -  oh->length = htons (p - sendbuf); - - -  if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) -    dst = &allspfrouters6; -  else -    dst = &on->linklocal_addr; - -  ospf6_send (on->ospf6_if->linklocal_addr, dst, on->ospf6_if, oh); - -  return 0; +	struct ospf6_neighbor *on; +	struct ospf6_header *oh; +	struct ospf6_dbdesc *dbdesc; +	u_char *p; +	struct ospf6_lsa *lsa; +	struct in6_addr *dst; + +	on = (struct ospf6_neighbor *)THREAD_ARG(thread); +	on->thread_send_dbdesc = (struct thread *)NULL; + +	if (on->state < OSPF6_NEIGHBOR_EXSTART) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_DBDESC, SEND)) +			zlog_debug( +				"Quit to send DbDesc to neighbor %s state %s", +				on->name, ospf6_neighbor_state_str[on->state]); +		return 0; +	} + +	/* set next thread if master */ +	if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)) +		thread_add_timer(master, ospf6_dbdesc_send, on, +				 on->ospf6_if->rxmt_interval, +				 &on->thread_send_dbdesc); + +	memset(sendbuf, 0, iobuflen); +	oh = (struct ospf6_header *)sendbuf; +	dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh +					 + sizeof(struct ospf6_header)); + +	/* if this is initial one, initialize sequence number for DbDesc */ +	if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT) +	    && (on->dbdesc_seqnum == 0)) { +		on->dbdesc_seqnum = monotime(NULL); +	} + +	dbdesc->options[0] = on->ospf6_if->area->options[0]; +	dbdesc->options[1] = on->ospf6_if->area->options[1]; +	dbdesc->options[2] = on->ospf6_if->area->options[2]; +	dbdesc->ifmtu = htons(on->ospf6_if->ifmtu); +	dbdesc->bits = on->dbdesc_bits; +	dbdesc->seqnum = htonl(on->dbdesc_seqnum); + +	/* if this is not initial one, set LSA headers in dbdesc */ +	p = (u_char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc)); +	if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)) { +		for (ALL_LSDB(on->dbdesc_list, lsa)) { +			ospf6_lsa_age_update_to_send(lsa, +						     on->ospf6_if->transdelay); + +			/* MTU check */ +			if (p - sendbuf + sizeof(struct ospf6_lsa_header) +			    > ospf6_packet_max(on->ospf6_if)) { +				ospf6_lsdb_lsa_unlock(lsa); +				break; +			} +			memcpy(p, lsa->header, sizeof(struct ospf6_lsa_header)); +			p += sizeof(struct ospf6_lsa_header); +		} +	} + +	oh->type = OSPF6_MESSAGE_TYPE_DBDESC; +	oh->length = htons(p - sendbuf); + + +	if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) +		dst = &allspfrouters6; +	else +		dst = &on->linklocal_addr; + +	ospf6_send(on->ospf6_if->linklocal_addr, dst, on->ospf6_if, oh); + +	return 0;  } -int -ospf6_dbdesc_send_newone (struct thread *thread) +int ospf6_dbdesc_send_newone(struct thread *thread)  { -  struct ospf6_neighbor *on; -  struct ospf6_lsa *lsa; -  unsigned int size = 0; - -  on = (struct ospf6_neighbor *) THREAD_ARG (thread); -  ospf6_lsdb_remove_all (on->dbdesc_list); - -  /* move LSAs from summary_list to dbdesc_list (within neighbor structure) -     so that ospf6_send_dbdesc () can send those LSAs */ -  size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc); -  for (ALL_LSDB(on->summary_list, lsa)) -    { -      if (size + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) -        { -          ospf6_lsdb_lsa_unlock (lsa); -          break; -        } - -      ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list); -      ospf6_lsdb_remove (lsa, on->summary_list); -      size += sizeof (struct ospf6_lsa_header); -    } - -  if (on->summary_list->count == 0) -    UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); - -  /* If slave, More bit check must be done here */ -  if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */ -      ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) && -      ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT)) -    thread_add_event (master, exchange_done, on, 0, NULL); - -  thread_execute (master, ospf6_dbdesc_send, on, 0); -  return 0; +	struct ospf6_neighbor *on; +	struct ospf6_lsa *lsa; +	unsigned int size = 0; + +	on = (struct ospf6_neighbor *)THREAD_ARG(thread); +	ospf6_lsdb_remove_all(on->dbdesc_list); + +	/* move LSAs from summary_list to dbdesc_list (within neighbor +	   structure) +	   so that ospf6_send_dbdesc () can send those LSAs */ +	size = sizeof(struct ospf6_lsa_header) + sizeof(struct ospf6_dbdesc); +	for (ALL_LSDB(on->summary_list, lsa)) { +		if (size + sizeof(struct ospf6_lsa_header) +		    > ospf6_packet_max(on->ospf6_if)) { +			ospf6_lsdb_lsa_unlock(lsa); +			break; +		} + +		ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->dbdesc_list); +		ospf6_lsdb_remove(lsa, on->summary_list); +		size += sizeof(struct ospf6_lsa_header); +	} + +	if (on->summary_list->count == 0) +		UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); + +	/* If slave, More bit check must be done here */ +	if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */ +	    !CHECK_FLAG(on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) +	    && !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)) +		thread_add_event(master, exchange_done, on, 0, NULL); + +	thread_execute(master, ospf6_dbdesc_send, on, 0); +	return 0;  } -int -ospf6_lsreq_send (struct thread *thread) +int ospf6_lsreq_send(struct thread *thread)  { -  struct ospf6_neighbor *on; -  struct ospf6_header *oh; -  struct ospf6_lsreq_entry *e; -  u_char *p; -  struct ospf6_lsa *lsa, *last_req; - -  on = (struct ospf6_neighbor *) THREAD_ARG (thread); -  on->thread_send_lsreq = (struct thread *) NULL; - -  /* LSReq will be sent only in ExStart or Loading */ -  if (on->state != OSPF6_NEIGHBOR_EXCHANGE && -      on->state != OSPF6_NEIGHBOR_LOADING) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND)) -        zlog_debug ("Quit to send LSReq to neighbor %s state %s", -		    on->name, ospf6_neighbor_state_str[on->state]); -      return 0; -    } - -  /* schedule loading_done if request list is empty */ -  if (on->request_list->count == 0) -    { -      thread_add_event (master, loading_done, on, 0, NULL); -      return 0; -    } - -  memset (sendbuf, 0, iobuflen); -  oh = (struct ospf6_header *) sendbuf; -  last_req = NULL; - -  /* set Request entries in lsreq */ -  p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header)); -  for (ALL_LSDB(on->request_list, lsa)) -    { -      /* MTU check */ -      if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if)) -        { -          ospf6_lsdb_lsa_unlock (lsa); -          break; -        } - -      e = (struct ospf6_lsreq_entry *) p; -      e->type = lsa->header->type; -      e->id = lsa->header->id; -      e->adv_router = lsa->header->adv_router; -      p += sizeof (struct ospf6_lsreq_entry); -      last_req = lsa; -    } - -  if (last_req != NULL) -    { -      if (on->last_ls_req != NULL) -	{ -	  ospf6_lsa_unlock (on->last_ls_req); -	} -      ospf6_lsa_lock (last_req); -      on->last_ls_req = last_req; -    } - -  oh->type = OSPF6_MESSAGE_TYPE_LSREQ; -  oh->length = htons (p - sendbuf); - -  if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) -    ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6, -              on->ospf6_if, oh); -  else -    ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr, -		on->ospf6_if, oh); - -  /* set next thread */ -  if (on->request_list->count != 0) -    { -      on->thread_send_lsreq = NULL; -      thread_add_timer(master, ospf6_lsreq_send, on, on->ospf6_if->rxmt_interval, -                       &on->thread_send_lsreq); -    } - -  return 0; +	struct ospf6_neighbor *on; +	struct ospf6_header *oh; +	struct ospf6_lsreq_entry *e; +	u_char *p; +	struct ospf6_lsa *lsa, *last_req; + +	on = (struct ospf6_neighbor *)THREAD_ARG(thread); +	on->thread_send_lsreq = (struct thread *)NULL; + +	/* LSReq will be sent only in ExStart or Loading */ +	if (on->state != OSPF6_NEIGHBOR_EXCHANGE +	    && on->state != OSPF6_NEIGHBOR_LOADING) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSREQ, SEND)) +			zlog_debug("Quit to send LSReq to neighbor %s state %s", +				   on->name, +				   ospf6_neighbor_state_str[on->state]); +		return 0; +	} + +	/* schedule loading_done if request list is empty */ +	if (on->request_list->count == 0) { +		thread_add_event(master, loading_done, on, 0, NULL); +		return 0; +	} + +	memset(sendbuf, 0, iobuflen); +	oh = (struct ospf6_header *)sendbuf; +	last_req = NULL; + +	/* set Request entries in lsreq */ +	p = (u_char *)((caddr_t)oh + sizeof(struct ospf6_header)); +	for (ALL_LSDB(on->request_list, lsa)) { +		/* MTU check */ +		if (p - sendbuf + sizeof(struct ospf6_lsreq_entry) +		    > ospf6_packet_max(on->ospf6_if)) { +			ospf6_lsdb_lsa_unlock(lsa); +			break; +		} + +		e = (struct ospf6_lsreq_entry *)p; +		e->type = lsa->header->type; +		e->id = lsa->header->id; +		e->adv_router = lsa->header->adv_router; +		p += sizeof(struct ospf6_lsreq_entry); +		last_req = lsa; +	} + +	if (last_req != NULL) { +		if (on->last_ls_req != NULL) { +			ospf6_lsa_unlock(on->last_ls_req); +		} +		ospf6_lsa_lock(last_req); +		on->last_ls_req = last_req; +	} + +	oh->type = OSPF6_MESSAGE_TYPE_LSREQ; +	oh->length = htons(p - sendbuf); + +	if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) +		ospf6_send(on->ospf6_if->linklocal_addr, &allspfrouters6, +			   on->ospf6_if, oh); +	else +		ospf6_send(on->ospf6_if->linklocal_addr, &on->linklocal_addr, +			   on->ospf6_if, oh); + +	/* set next thread */ +	if (on->request_list->count != 0) { +		on->thread_send_lsreq = NULL; +		thread_add_timer(master, ospf6_lsreq_send, on, +				 on->ospf6_if->rxmt_interval, +				 &on->thread_send_lsreq); +	} + +	return 0;  } -int -ospf6_lsupdate_send_neighbor (struct thread *thread) +int ospf6_lsupdate_send_neighbor(struct thread *thread)  { -  struct ospf6_neighbor *on; -  struct ospf6_header *oh; -  struct ospf6_lsupdate *lsupdate; -  u_char *p; -  int lsa_cnt; -  struct ospf6_lsa *lsa; - -  on = (struct ospf6_neighbor *) THREAD_ARG (thread); -  on->thread_send_lsupdate = (struct thread *) NULL; - -  if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) -    zlog_debug ("LSUpdate to neighbor %s", on->name); - -  if (on->state < OSPF6_NEIGHBOR_EXCHANGE) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) -        zlog_debug ("Quit to send (neighbor state %s)", -		    ospf6_neighbor_state_str[on->state]); -      return 0; -    } - -  memset (sendbuf, 0, iobuflen); -  oh = (struct ospf6_header *) sendbuf; -  lsupdate = (struct ospf6_lsupdate *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); - -  p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); -  lsa_cnt = 0; - -  /* lsupdate_list lists those LSA which doesn't need to be -     retransmitted. remove those from the list */ -  for (ALL_LSDB(on->lsupdate_list, lsa)) -    { -      /* MTU check */ -      if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header)) -	   > ospf6_packet_max(on->ospf6_if)) -	{ -	  ospf6_lsdb_lsa_unlock (lsa); -	  break; -	} - -      ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay); -      memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header)); -      p += OSPF6_LSA_SIZE (lsa->header); -      lsa_cnt++; - -      assert (lsa->lock == 2); -      ospf6_lsdb_remove (lsa, on->lsupdate_list); -    } - -  if (lsa_cnt) -    { -      oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; -      oh->length = htons (p - sendbuf); -      lsupdate->lsa_number = htonl (lsa_cnt); - -      if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) || -	  (on->ospf6_if->state == OSPF6_INTERFACE_DR) || -	  (on->ospf6_if->state == OSPF6_INTERFACE_BDR)) -	ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6, -		    on->ospf6_if, oh); -      else -	ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr, -		    on->ospf6_if, oh); -    } - -  /* The addresses used for retransmissions are different from those sent the -     first time and so we need to separate them here. -  */ -  memset (sendbuf, 0, iobuflen); -  oh = (struct ospf6_header *) sendbuf; -  lsupdate = (struct ospf6_lsupdate *) -    ((caddr_t) oh + sizeof (struct ospf6_header)); -  p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); -  lsa_cnt = 0; - -  for (ALL_LSDB(on->retrans_list, lsa)) -    { -      /* MTU check */ -      if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header)) -	   > ospf6_packet_max(on->ospf6_if)) -	{ -	  ospf6_lsdb_lsa_unlock (lsa); -	  break; -	} - -      ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay); -      memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header)); -      p += OSPF6_LSA_SIZE (lsa->header); -      lsa_cnt++; -    } - -  if (lsa_cnt) -    { -      oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; -      oh->length = htons (p - sendbuf); -      lsupdate->lsa_number = htonl (lsa_cnt); - -      if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) -	ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6, -		    on->ospf6_if, oh); -      else -	ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr, -		    on->ospf6_if, oh); -    } - -  if (on->lsupdate_list->count != 0) { -    on->thread_send_lsupdate = NULL; -    thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0, -                     &on->thread_send_lsupdate); -  } -  else if (on->retrans_list->count != 0) { -    on->thread_send_lsupdate = NULL; -    thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, on->ospf6_if->rxmt_interval, -                     &on->thread_send_lsupdate); -  } -  return 0; +	struct ospf6_neighbor *on; +	struct ospf6_header *oh; +	struct ospf6_lsupdate *lsupdate; +	u_char *p; +	int lsa_cnt; +	struct ospf6_lsa *lsa; + +	on = (struct ospf6_neighbor *)THREAD_ARG(thread); +	on->thread_send_lsupdate = (struct thread *)NULL; + +	if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) +		zlog_debug("LSUpdate to neighbor %s", on->name); + +	if (on->state < OSPF6_NEIGHBOR_EXCHANGE) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) +			zlog_debug("Quit to send (neighbor state %s)", +				   ospf6_neighbor_state_str[on->state]); +		return 0; +	} + +	memset(sendbuf, 0, iobuflen); +	oh = (struct ospf6_header *)sendbuf; +	lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh +					     + sizeof(struct ospf6_header)); + +	p = (u_char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); +	lsa_cnt = 0; + +	/* lsupdate_list lists those LSA which doesn't need to be +	   retransmitted. remove those from the list */ +	for (ALL_LSDB(on->lsupdate_list, lsa)) { +		/* MTU check */ +		if ((p - sendbuf + (unsigned int)OSPF6_LSA_SIZE(lsa->header)) +		    > ospf6_packet_max(on->ospf6_if)) { +			ospf6_lsdb_lsa_unlock(lsa); +			break; +		} + +		ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); +		memcpy(p, lsa->header, OSPF6_LSA_SIZE(lsa->header)); +		p += OSPF6_LSA_SIZE(lsa->header); +		lsa_cnt++; + +		assert(lsa->lock == 2); +		ospf6_lsdb_remove(lsa, on->lsupdate_list); +	} + +	if (lsa_cnt) { +		oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; +		oh->length = htons(p - sendbuf); +		lsupdate->lsa_number = htonl(lsa_cnt); + +		if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) +		    || (on->ospf6_if->state == OSPF6_INTERFACE_DR) +		    || (on->ospf6_if->state == OSPF6_INTERFACE_BDR)) +			ospf6_send(on->ospf6_if->linklocal_addr, +				   &allspfrouters6, on->ospf6_if, oh); +		else +			ospf6_send(on->ospf6_if->linklocal_addr, +				   &on->linklocal_addr, on->ospf6_if, oh); +	} + +	/* The addresses used for retransmissions are different from those sent +	   the +	   first time and so we need to separate them here. +	*/ +	memset(sendbuf, 0, iobuflen); +	oh = (struct ospf6_header *)sendbuf; +	lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh +					     + sizeof(struct ospf6_header)); +	p = (u_char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); +	lsa_cnt = 0; + +	for (ALL_LSDB(on->retrans_list, lsa)) { +		/* MTU check */ +		if ((p - sendbuf + (unsigned int)OSPF6_LSA_SIZE(lsa->header)) +		    > ospf6_packet_max(on->ospf6_if)) { +			ospf6_lsdb_lsa_unlock(lsa); +			break; +		} + +		ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); +		memcpy(p, lsa->header, OSPF6_LSA_SIZE(lsa->header)); +		p += OSPF6_LSA_SIZE(lsa->header); +		lsa_cnt++; +	} + +	if (lsa_cnt) { +		oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; +		oh->length = htons(p - sendbuf); +		lsupdate->lsa_number = htonl(lsa_cnt); + +		if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) +			ospf6_send(on->ospf6_if->linklocal_addr, +				   &allspfrouters6, on->ospf6_if, oh); +		else +			ospf6_send(on->ospf6_if->linklocal_addr, +				   &on->linklocal_addr, on->ospf6_if, oh); +	} + +	if (on->lsupdate_list->count != 0) { +		on->thread_send_lsupdate = NULL; +		thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0, +				 &on->thread_send_lsupdate); +	} else if (on->retrans_list->count != 0) { +		on->thread_send_lsupdate = NULL; +		thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, +				 on->ospf6_if->rxmt_interval, +				 &on->thread_send_lsupdate); +	} +	return 0;  } -int -ospf6_lsupdate_send_interface (struct thread *thread) +int ospf6_lsupdate_send_interface(struct thread *thread)  { -  struct ospf6_interface *oi; -  struct ospf6_header *oh; -  struct ospf6_lsupdate *lsupdate; -  u_char *p; -  int lsa_cnt; -  struct ospf6_lsa *lsa; - -  oi = (struct ospf6_interface *) THREAD_ARG (thread); -  oi->thread_send_lsupdate = (struct thread *) NULL; - -  if (oi->state <= OSPF6_INTERFACE_WAITING) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) -        zlog_debug ("Quit to send LSUpdate to interface %s state %s", -		    oi->interface->name, ospf6_interface_state_str[oi->state]); -      return 0; -    } - -  /* if we have nothing to send, return */ -  if (oi->lsupdate_list->count == 0) -    return 0; - -  memset (sendbuf, 0, iobuflen); -  oh = (struct ospf6_header *) sendbuf; -  lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh + -				       sizeof (struct ospf6_header)); - -  p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); -  lsa_cnt = 0; - -  for (ALL_LSDB(oi->lsupdate_list, lsa)) -    { -      /* MTU check */ -      if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header))) -	   > ospf6_packet_max(oi)) -	{ -	  ospf6_lsdb_lsa_unlock (lsa); -	  break; -	} - -      ospf6_lsa_age_update_to_send (lsa, oi->transdelay); -      memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header)); -      p += OSPF6_LSA_SIZE (lsa->header); -      lsa_cnt++; - -      assert (lsa->lock == 2); -      ospf6_lsdb_remove (lsa, oi->lsupdate_list); -    } - -  if (lsa_cnt) -    { -      lsupdate->lsa_number = htonl (lsa_cnt); - -      oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; -      oh->length = htons (p - sendbuf); - -      if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) || -	  (oi->state == OSPF6_INTERFACE_DR) || -	  (oi->state == OSPF6_INTERFACE_BDR)) -	ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh); -      else -	ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh); - -    } - -  if (oi->lsupdate_list->count > 0) -    { -      oi->thread_send_lsupdate = NULL; -      thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0, -                       &oi->thread_send_lsupdate); -    } - -  return 0; +	struct ospf6_interface *oi; +	struct ospf6_header *oh; +	struct ospf6_lsupdate *lsupdate; +	u_char *p; +	int lsa_cnt; +	struct ospf6_lsa *lsa; + +	oi = (struct ospf6_interface *)THREAD_ARG(thread); +	oi->thread_send_lsupdate = (struct thread *)NULL; + +	if (oi->state <= OSPF6_INTERFACE_WAITING) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) +			zlog_debug( +				"Quit to send LSUpdate to interface %s state %s", +				oi->interface->name, +				ospf6_interface_state_str[oi->state]); +		return 0; +	} + +	/* if we have nothing to send, return */ +	if (oi->lsupdate_list->count == 0) +		return 0; + +	memset(sendbuf, 0, iobuflen); +	oh = (struct ospf6_header *)sendbuf; +	lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh +					     + sizeof(struct ospf6_header)); + +	p = (u_char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); +	lsa_cnt = 0; + +	for (ALL_LSDB(oi->lsupdate_list, lsa)) { +		/* MTU check */ +		if ((p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE(lsa->header))) +		    > ospf6_packet_max(oi)) { +			ospf6_lsdb_lsa_unlock(lsa); +			break; +		} + +		ospf6_lsa_age_update_to_send(lsa, oi->transdelay); +		memcpy(p, lsa->header, OSPF6_LSA_SIZE(lsa->header)); +		p += OSPF6_LSA_SIZE(lsa->header); +		lsa_cnt++; + +		assert(lsa->lock == 2); +		ospf6_lsdb_remove(lsa, oi->lsupdate_list); +	} + +	if (lsa_cnt) { +		lsupdate->lsa_number = htonl(lsa_cnt); + +		oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; +		oh->length = htons(p - sendbuf); + +		if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) +		    || (oi->state == OSPF6_INTERFACE_DR) +		    || (oi->state == OSPF6_INTERFACE_BDR)) +			ospf6_send(oi->linklocal_addr, &allspfrouters6, oi, oh); +		else +			ospf6_send(oi->linklocal_addr, &alldrouters6, oi, oh); +	} + +	if (oi->lsupdate_list->count > 0) { +		oi->thread_send_lsupdate = NULL; +		thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0, +				 &oi->thread_send_lsupdate); +	} + +	return 0;  } -int -ospf6_lsack_send_neighbor (struct thread *thread) +int ospf6_lsack_send_neighbor(struct thread *thread)  { -  struct ospf6_neighbor *on; -  struct ospf6_header *oh; -  u_char *p; -  struct ospf6_lsa *lsa; -  int lsa_cnt = 0; - -  on = (struct ospf6_neighbor *) THREAD_ARG (thread); -  on->thread_send_lsack = (struct thread *) NULL; - -  if (on->state < OSPF6_NEIGHBOR_EXCHANGE) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND)) -        zlog_debug ("Quit to send LSAck to neighbor %s state %s", -		    on->name, ospf6_neighbor_state_str[on->state]); -      return 0; -    } - -  /* if we have nothing to send, return */ -  if (on->lsack_list->count == 0) -    return 0; - -  memset (sendbuf, 0, iobuflen); -  oh = (struct ospf6_header *) sendbuf; - -  p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header)); - -  for (ALL_LSDB(on->lsack_list, lsa)) -    { -      /* MTU check */ -      if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) -	{ -	  /* if we run out of packet size/space here, -	     better to try again soon. */ -	  THREAD_OFF (on->thread_send_lsack); -      thread_add_event (master, ospf6_lsack_send_neighbor, on, 0, &on->thread_send_lsack); - -	  ospf6_lsdb_lsa_unlock (lsa); -	  break; -	} - -      ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay); -      memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header)); -      p += sizeof (struct ospf6_lsa_header); - -      assert (lsa->lock == 2); -      ospf6_lsdb_remove (lsa, on->lsack_list); -      lsa_cnt++; -    } - -  if (lsa_cnt) -    { -      oh->type = OSPF6_MESSAGE_TYPE_LSACK; -      oh->length = htons (p - sendbuf); - -      ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr, -		  on->ospf6_if, oh); -    } - -  if (on->lsack_list->count > 0) -    thread_add_event (master, ospf6_lsack_send_neighbor, on, 0, &on->thread_send_lsack); - -  return 0; +	struct ospf6_neighbor *on; +	struct ospf6_header *oh; +	u_char *p; +	struct ospf6_lsa *lsa; +	int lsa_cnt = 0; + +	on = (struct ospf6_neighbor *)THREAD_ARG(thread); +	on->thread_send_lsack = (struct thread *)NULL; + +	if (on->state < OSPF6_NEIGHBOR_EXCHANGE) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND)) +			zlog_debug("Quit to send LSAck to neighbor %s state %s", +				   on->name, +				   ospf6_neighbor_state_str[on->state]); +		return 0; +	} + +	/* if we have nothing to send, return */ +	if (on->lsack_list->count == 0) +		return 0; + +	memset(sendbuf, 0, iobuflen); +	oh = (struct ospf6_header *)sendbuf; + +	p = (u_char *)((caddr_t)oh + sizeof(struct ospf6_header)); + +	for (ALL_LSDB(on->lsack_list, lsa)) { +		/* MTU check */ +		if (p - sendbuf + sizeof(struct ospf6_lsa_header) +		    > ospf6_packet_max(on->ospf6_if)) { +			/* if we run out of packet size/space here, +			   better to try again soon. */ +			THREAD_OFF(on->thread_send_lsack); +			thread_add_event(master, ospf6_lsack_send_neighbor, on, +					 0, &on->thread_send_lsack); + +			ospf6_lsdb_lsa_unlock(lsa); +			break; +		} + +		ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); +		memcpy(p, lsa->header, sizeof(struct ospf6_lsa_header)); +		p += sizeof(struct ospf6_lsa_header); + +		assert(lsa->lock == 2); +		ospf6_lsdb_remove(lsa, on->lsack_list); +		lsa_cnt++; +	} + +	if (lsa_cnt) { +		oh->type = OSPF6_MESSAGE_TYPE_LSACK; +		oh->length = htons(p - sendbuf); + +		ospf6_send(on->ospf6_if->linklocal_addr, &on->linklocal_addr, +			   on->ospf6_if, oh); +	} + +	if (on->lsack_list->count > 0) +		thread_add_event(master, ospf6_lsack_send_neighbor, on, 0, +				 &on->thread_send_lsack); + +	return 0;  } -int -ospf6_lsack_send_interface (struct thread *thread) +int ospf6_lsack_send_interface(struct thread *thread)  { -  struct ospf6_interface *oi; -  struct ospf6_header *oh; -  u_char *p; -  struct ospf6_lsa *lsa; -  int lsa_cnt = 0; - -  oi = (struct ospf6_interface *) THREAD_ARG (thread); -  oi->thread_send_lsack = (struct thread *) NULL; - -  if (oi->state <= OSPF6_INTERFACE_WAITING) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND)) -        zlog_debug ("Quit to send LSAck to interface %s state %s", -		    oi->interface->name, ospf6_interface_state_str[oi->state]); -      return 0; -    } - -  /* if we have nothing to send, return */ -  if (oi->lsack_list->count == 0) -    return 0; - -  memset (sendbuf, 0, iobuflen); -  oh = (struct ospf6_header *) sendbuf; - -  p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header)); - -  for (ALL_LSDB(oi->lsack_list, lsa)) -    { -      /* MTU check */ -      if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi)) -	{ -	  /* if we run out of packet size/space here, -	     better to try again soon. */ -	  THREAD_OFF (oi->thread_send_lsack); -      thread_add_event (master, ospf6_lsack_send_interface, oi, 0, -                        &oi->thread_send_lsack); - -	  ospf6_lsdb_lsa_unlock (lsa); -	  break; -	} - -      ospf6_lsa_age_update_to_send (lsa, oi->transdelay); -      memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header)); -      p += sizeof (struct ospf6_lsa_header); - -      assert (lsa->lock == 2); -      ospf6_lsdb_remove (lsa, oi->lsack_list); -      lsa_cnt++; -    } - -  if (lsa_cnt) -    { -      oh->type = OSPF6_MESSAGE_TYPE_LSACK; -      oh->length = htons (p - sendbuf); - -      if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) || -	  (oi->state == OSPF6_INTERFACE_DR) || -	  (oi->state == OSPF6_INTERFACE_BDR)) -	ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh); -      else -	ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh); -    } - -  if (oi->lsack_list->count > 0) -    thread_add_event (master, ospf6_lsack_send_interface, oi, 0, &oi->thread_send_lsack); - -  return 0; +	struct ospf6_interface *oi; +	struct ospf6_header *oh; +	u_char *p; +	struct ospf6_lsa *lsa; +	int lsa_cnt = 0; + +	oi = (struct ospf6_interface *)THREAD_ARG(thread); +	oi->thread_send_lsack = (struct thread *)NULL; + +	if (oi->state <= OSPF6_INTERFACE_WAITING) { +		if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND)) +			zlog_debug( +				"Quit to send LSAck to interface %s state %s", +				oi->interface->name, +				ospf6_interface_state_str[oi->state]); +		return 0; +	} + +	/* if we have nothing to send, return */ +	if (oi->lsack_list->count == 0) +		return 0; + +	memset(sendbuf, 0, iobuflen); +	oh = (struct ospf6_header *)sendbuf; + +	p = (u_char *)((caddr_t)oh + sizeof(struct ospf6_header)); + +	for (ALL_LSDB(oi->lsack_list, lsa)) { +		/* MTU check */ +		if (p - sendbuf + sizeof(struct ospf6_lsa_header) +		    > ospf6_packet_max(oi)) { +			/* if we run out of packet size/space here, +			   better to try again soon. */ +			THREAD_OFF(oi->thread_send_lsack); +			thread_add_event(master, ospf6_lsack_send_interface, oi, +					 0, &oi->thread_send_lsack); + +			ospf6_lsdb_lsa_unlock(lsa); +			break; +		} + +		ospf6_lsa_age_update_to_send(lsa, oi->transdelay); +		memcpy(p, lsa->header, sizeof(struct ospf6_lsa_header)); +		p += sizeof(struct ospf6_lsa_header); + +		assert(lsa->lock == 2); +		ospf6_lsdb_remove(lsa, oi->lsack_list); +		lsa_cnt++; +	} + +	if (lsa_cnt) { +		oh->type = OSPF6_MESSAGE_TYPE_LSACK; +		oh->length = htons(p - sendbuf); + +		if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) +		    || (oi->state == OSPF6_INTERFACE_DR) +		    || (oi->state == OSPF6_INTERFACE_BDR)) +			ospf6_send(oi->linklocal_addr, &allspfrouters6, oi, oh); +		else +			ospf6_send(oi->linklocal_addr, &alldrouters6, oi, oh); +	} + +	if (oi->lsack_list->count > 0) +		thread_add_event(master, ospf6_lsack_send_interface, oi, 0, +				 &oi->thread_send_lsack); + +	return 0;  } @@ -2335,44 +2314,42 @@ DEFUN (debug_ospf6_message,         "Debug only sending message\n"         "Debug only receiving message\n")  { -  int idx_packet = 3; -  int idx_send_recv = 4; -  unsigned char level = 0; -  int type = 0; -  int i; - -  /* check type */ -  if (! strncmp (argv[idx_packet]->arg, "u", 1)) -    type = OSPF6_MESSAGE_TYPE_UNKNOWN; -  else if (! strncmp (argv[idx_packet]->arg, "h", 1)) -    type = OSPF6_MESSAGE_TYPE_HELLO; -  else if (! strncmp (argv[idx_packet]->arg, "d", 1)) -    type = OSPF6_MESSAGE_TYPE_DBDESC; -  else if (! strncmp (argv[idx_packet]->arg, "lsr", 3)) -    type = OSPF6_MESSAGE_TYPE_LSREQ; -  else if (! strncmp (argv[idx_packet]->arg, "lsu", 3)) -    type = OSPF6_MESSAGE_TYPE_LSUPDATE; -  else if (! strncmp (argv[idx_packet]->arg, "lsa", 3)) -    type = OSPF6_MESSAGE_TYPE_LSACK; -  else if (! strncmp (argv[idx_packet]->arg, "a", 1)) -    type = OSPF6_MESSAGE_TYPE_ALL; - -  if (argc == 4) -    level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV; -  else if (! strncmp (argv[idx_send_recv]->arg, "s", 1)) -    level = OSPF6_DEBUG_MESSAGE_SEND; -  else if (! strncmp (argv[idx_send_recv]->arg, "r", 1)) -    level = OSPF6_DEBUG_MESSAGE_RECV; - -  if (type == OSPF6_MESSAGE_TYPE_ALL) -    { -      for (i = 0; i < 6; i++) -        OSPF6_DEBUG_MESSAGE_ON (i, level); -    } -  else -    OSPF6_DEBUG_MESSAGE_ON (type, level); - -  return CMD_SUCCESS; +	int idx_packet = 3; +	int idx_send_recv = 4; +	unsigned char level = 0; +	int type = 0; +	int i; + +	/* check type */ +	if (!strncmp(argv[idx_packet]->arg, "u", 1)) +		type = OSPF6_MESSAGE_TYPE_UNKNOWN; +	else if (!strncmp(argv[idx_packet]->arg, "h", 1)) +		type = OSPF6_MESSAGE_TYPE_HELLO; +	else if (!strncmp(argv[idx_packet]->arg, "d", 1)) +		type = OSPF6_MESSAGE_TYPE_DBDESC; +	else if (!strncmp(argv[idx_packet]->arg, "lsr", 3)) +		type = OSPF6_MESSAGE_TYPE_LSREQ; +	else if (!strncmp(argv[idx_packet]->arg, "lsu", 3)) +		type = OSPF6_MESSAGE_TYPE_LSUPDATE; +	else if (!strncmp(argv[idx_packet]->arg, "lsa", 3)) +		type = OSPF6_MESSAGE_TYPE_LSACK; +	else if (!strncmp(argv[idx_packet]->arg, "a", 1)) +		type = OSPF6_MESSAGE_TYPE_ALL; + +	if (argc == 4) +		level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV; +	else if (!strncmp(argv[idx_send_recv]->arg, "s", 1)) +		level = OSPF6_DEBUG_MESSAGE_SEND; +	else if (!strncmp(argv[idx_send_recv]->arg, "r", 1)) +		level = OSPF6_DEBUG_MESSAGE_RECV; + +	if (type == OSPF6_MESSAGE_TYPE_ALL) { +		for (i = 0; i < 6; i++) +			OSPF6_DEBUG_MESSAGE_ON(i, level); +	} else +		OSPF6_DEBUG_MESSAGE_ON(type, level); + +	return CMD_SUCCESS;  }  DEFUN (no_debug_ospf6_message, @@ -2392,110 +2369,100 @@ DEFUN (no_debug_ospf6_message,         "Debug only sending message\n"         "Debug only receiving message\n")  { -  int idx_packet = 4; -  int idx_send_recv = 5; -  unsigned char level = 0; -  int type = 0; -  int i; - -  /* check type */ -  if (! strncmp (argv[idx_packet]->arg, "u", 1)) -    type = OSPF6_MESSAGE_TYPE_UNKNOWN; -  else if (! strncmp (argv[idx_packet]->arg, "h", 1)) -    type = OSPF6_MESSAGE_TYPE_HELLO; -  else if (! strncmp (argv[idx_packet]->arg, "d", 1)) -    type = OSPF6_MESSAGE_TYPE_DBDESC; -  else if (! strncmp (argv[idx_packet]->arg, "lsr", 3)) -    type = OSPF6_MESSAGE_TYPE_LSREQ; -  else if (! strncmp (argv[idx_packet]->arg, "lsu", 3)) -    type = OSPF6_MESSAGE_TYPE_LSUPDATE; -  else if (! strncmp (argv[idx_packet]->arg, "lsa", 3)) -    type = OSPF6_MESSAGE_TYPE_LSACK; -  else if (! strncmp (argv[idx_packet]->arg, "a", 1)) -    type = OSPF6_MESSAGE_TYPE_ALL; - -  if (argc == 5) -    level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV; -  else if (! strncmp (argv[idx_send_recv]->arg, "s", 1)) -    level = OSPF6_DEBUG_MESSAGE_SEND; -  else if (! strncmp (argv[idx_send_recv]->arg, "r", 1)) -    level = OSPF6_DEBUG_MESSAGE_RECV; - -  if (type == OSPF6_MESSAGE_TYPE_ALL) -    { -      for (i = 0; i < 6; i++) -        OSPF6_DEBUG_MESSAGE_OFF (i, level); -    } -  else -    OSPF6_DEBUG_MESSAGE_OFF (type, level); - -  return CMD_SUCCESS; +	int idx_packet = 4; +	int idx_send_recv = 5; +	unsigned char level = 0; +	int type = 0; +	int i; + +	/* check type */ +	if (!strncmp(argv[idx_packet]->arg, "u", 1)) +		type = OSPF6_MESSAGE_TYPE_UNKNOWN; +	else if (!strncmp(argv[idx_packet]->arg, "h", 1)) +		type = OSPF6_MESSAGE_TYPE_HELLO; +	else if (!strncmp(argv[idx_packet]->arg, "d", 1)) +		type = OSPF6_MESSAGE_TYPE_DBDESC; +	else if (!strncmp(argv[idx_packet]->arg, "lsr", 3)) +		type = OSPF6_MESSAGE_TYPE_LSREQ; +	else if (!strncmp(argv[idx_packet]->arg, "lsu", 3)) +		type = OSPF6_MESSAGE_TYPE_LSUPDATE; +	else if (!strncmp(argv[idx_packet]->arg, "lsa", 3)) +		type = OSPF6_MESSAGE_TYPE_LSACK; +	else if (!strncmp(argv[idx_packet]->arg, "a", 1)) +		type = OSPF6_MESSAGE_TYPE_ALL; + +	if (argc == 5) +		level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV; +	else if (!strncmp(argv[idx_send_recv]->arg, "s", 1)) +		level = OSPF6_DEBUG_MESSAGE_SEND; +	else if (!strncmp(argv[idx_send_recv]->arg, "r", 1)) +		level = OSPF6_DEBUG_MESSAGE_RECV; + +	if (type == OSPF6_MESSAGE_TYPE_ALL) { +		for (i = 0; i < 6; i++) +			OSPF6_DEBUG_MESSAGE_OFF(i, level); +	} else +		OSPF6_DEBUG_MESSAGE_OFF(type, level); + +	return CMD_SUCCESS;  } -int -config_write_ospf6_debug_message (struct vty *vty) +int config_write_ospf6_debug_message(struct vty *vty)  { -  const char *type_str[] = {"unknown", "hello", "dbdesc", -                      "lsreq", "lsupdate", "lsack"}; -  unsigned char s = 0, r = 0; -  int i; - -  for (i = 0; i < 6; i++) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (i, SEND)) -        s |= 1 << i; -      if (IS_OSPF6_DEBUG_MESSAGE (i, RECV)) -        r |= 1 << i; -    } - -  if (s == 0x3f && r == 0x3f) -    { -      vty_out (vty, "debug ospf6 message all\n"); -      return 0; -    } - -  if (s == 0x3f && r == 0) -    { -      vty_out (vty, "debug ospf6 message all send\n"); -      return 0; -    } -  else if (s == 0 && r == 0x3f) -    { -      vty_out (vty, "debug ospf6 message all recv\n"); -      return 0; -    } - -  /* Unknown message is logged by default */ -  if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) && -      ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -    vty_out (vty, "no debug ospf6 message unknown\n"); -  else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND)) -    vty_out (vty, "no debug ospf6 message unknown send\n"); -  else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) -    vty_out (vty, "no debug ospf6 message unknown recv\n"); - -  for (i = 1; i < 6; i++) -    { -      if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) && -          IS_OSPF6_DEBUG_MESSAGE (i, RECV)) -        vty_out (vty, "debug ospf6 message %s\n", type_str[i]); -      else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND)) -        vty_out (vty, "debug ospf6 message %s send\n", type_str[i]); -      else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV)) -        vty_out (vty, "debug ospf6 message %s recv\n", type_str[i]); -    } - -  return 0; +	const char *type_str[] = {"unknown", "hello",    "dbdesc", +				  "lsreq",   "lsupdate", "lsack"}; +	unsigned char s = 0, r = 0; +	int i; + +	for (i = 0; i < 6; i++) { +		if (IS_OSPF6_DEBUG_MESSAGE(i, SEND)) +			s |= 1 << i; +		if (IS_OSPF6_DEBUG_MESSAGE(i, RECV)) +			r |= 1 << i; +	} + +	if (s == 0x3f && r == 0x3f) { +		vty_out(vty, "debug ospf6 message all\n"); +		return 0; +	} + +	if (s == 0x3f && r == 0) { +		vty_out(vty, "debug ospf6 message all send\n"); +		return 0; +	} else if (s == 0 && r == 0x3f) { +		vty_out(vty, "debug ospf6 message all recv\n"); +		return 0; +	} + +	/* Unknown message is logged by default */ +	if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) +	    && !IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +		vty_out(vty, "no debug ospf6 message unknown\n"); +	else if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, SEND)) +		vty_out(vty, "no debug ospf6 message unknown send\n"); +	else if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) +		vty_out(vty, "no debug ospf6 message unknown recv\n"); + +	for (i = 1; i < 6; i++) { +		if (IS_OSPF6_DEBUG_MESSAGE(i, SEND) +		    && IS_OSPF6_DEBUG_MESSAGE(i, RECV)) +			vty_out(vty, "debug ospf6 message %s\n", type_str[i]); +		else if (IS_OSPF6_DEBUG_MESSAGE(i, SEND)) +			vty_out(vty, "debug ospf6 message %s send\n", +				type_str[i]); +		else if (IS_OSPF6_DEBUG_MESSAGE(i, RECV)) +			vty_out(vty, "debug ospf6 message %s recv\n", +				type_str[i]); +	} + +	return 0;  } -void -install_element_ospf6_debug_message (void) +void install_element_ospf6_debug_message(void)  { -  install_element (ENABLE_NODE, &debug_ospf6_message_cmd); -  install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd); -  install_element (CONFIG_NODE, &debug_ospf6_message_cmd); -  install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd); +	install_element(ENABLE_NODE, &debug_ospf6_message_cmd); +	install_element(ENABLE_NODE, &no_debug_ospf6_message_cmd); +	install_element(CONFIG_NODE, &debug_ospf6_message_cmd); +	install_element(CONFIG_NODE, &no_debug_ospf6_message_cmd);  } - -  | 
