summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_message.c
diff options
context:
space:
mode:
authorDinesh Dutt <ddutt@cumulusnetworks.com>2013-08-24 09:55:07 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2013-11-08 03:15:42 +0100
commiteb82e9ee81792f86548d4937486b5dcbbd411a98 (patch)
tree9c1f216017923cc40af71755506dc35c5c2c0fbc /ospf6d/ospf6_message.c
parentospf6d: add p2p interface support (diff)
downloadfrr-eb82e9ee81792f86548d4937486b5dcbbd411a98.tar.xz
frr-eb82e9ee81792f86548d4937486b5dcbbd411a98.zip
ospf6d: fix neighbor state machine (faster lsdb sync, RFC compliance)
The OSPFv3 code doesn't do the following things right as part of an adjacency bringup: - Transmit DbDesc frames appropriately to ensure faster state transition to Loading state - Transmit LsReq frames when switching to exchange state and on receipt of an LS update in Loading state - Requesting LSAs multiple times in LsReq. It currently uses retransmit timer expiry to send the LsReq and DbDesc frames which significantly slows down large lsdb syncs. Signed-off-by: Dinesh G Dutt <ddutt at cumulusnetworks.com> Reviewed-by: Scott Feldman <sfeldma at cumulusnetworks.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'ospf6d/ospf6_message.c')
-rw-r--r--ospf6d/ospf6_message.c56
1 files changed, 29 insertions, 27 deletions
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index 31db9a4ba..dcbb36bf5 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -517,20 +517,20 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Add request (No database copy)");
- ospf6_lsdb_add (his, on->request_list);
+ 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 (his, on->request_list);
+ 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);
}
+ ospf6_lsa_delete (his);
}
assert (p == OSPF6_MESSAGE_END (oh));
@@ -539,7 +539,7 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
on->dbdesc_seqnum ++;
/* schedule send lsreq */
- if (on->thread_send_lsreq == NULL)
+ if (on->request_list->count && (on->thread_send_lsreq == NULL))
on->thread_send_lsreq =
thread_add_event (master, ospf6_lsreq_send, on, 0);
@@ -735,10 +735,9 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Add request-list: %s", his->name);
- ospf6_lsdb_add (his, on->request_list);
+ ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
}
- else
- ospf6_lsa_delete (his);
+ ospf6_lsa_delete (his);
}
assert (p == OSPF6_MESSAGE_END (oh));
@@ -747,7 +746,8 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
/* schedule send lsreq */
- if (on->thread_send_lsreq == NULL)
+ if ((on->thread_send_lsreq == NULL) &&
+ (on->request_list->count))
on->thread_send_lsreq =
thread_add_event (master, ospf6_lsreq_send, on, 0);
@@ -1351,19 +1351,6 @@ ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst,
assert (p == OSPF6_MESSAGE_END (oh));
- /* RFC2328 Section 10.9: When the neighbor responds to these requests
- with the proper Link State Update packet(s), the Link state request
- list is truncated and a new Link State Request packet is sent. */
- /* send new Link State Request packet if this LS Update packet
- can be recognized as a response to our previous LS Request */
- if (! IN6_IS_ADDR_MULTICAST (dst) &&
- (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
- on->state == OSPF6_NEIGHBOR_LOADING))
- {
- THREAD_OFF (on->thread_send_lsreq);
- on->thread_send_lsreq =
- thread_add_event (master, ospf6_lsreq_send, on, 0);
- }
}
static void
@@ -1907,7 +1894,7 @@ ospf6_lsreq_send (struct thread *thread)
struct ospf6_header *oh;
struct ospf6_lsreq_entry *e;
u_char *p;
- struct ospf6_lsa *lsa;
+ struct ospf6_lsa *lsa, *last_req;
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
on->thread_send_lsreq = (struct thread *) NULL;
@@ -1929,13 +1916,9 @@ ospf6_lsreq_send (struct thread *thread)
return 0;
}
- /* set next thread */
- on->thread_send_lsreq =
- thread_add_timer (master, ospf6_lsreq_send, on,
- on->ospf6_if->rxmt_interval);
-
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));
@@ -1954,6 +1937,17 @@ ospf6_lsreq_send (struct thread *thread)
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;
@@ -1966,6 +1960,14 @@ ospf6_lsreq_send (struct thread *thread)
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 =
+ thread_add_timer (master, ospf6_lsreq_send, on,
+ on->ospf6_if->rxmt_interval);
+ }
+
return 0;
}