ospf6d: add p2p interface support
Signed-off-by: Dinesh G Dutt <ddutt at cumulusnetworks.com>
Signed-off-by: Ayan Banerjee <ayabaner at gmail.com>
Reviewed-by: Scott Feldman <sfeldma at cumulusnetworks.com>
Reviewed-by: James Li <jli at cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index b35aa1a..31db9a4 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -1785,6 +1785,7 @@
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;
@@ -1848,8 +1849,14 @@
oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
oh->length = htons (p - sendbuf);
- ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
- on->ospf6_if, oh);
+
+ 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;
}
@@ -1952,8 +1959,13 @@
oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
oh->length = htons (p - sendbuf);
- ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+ 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);
+
return 0;
}
@@ -1964,7 +1976,7 @@
struct ospf6_header *oh;
struct ospf6_lsupdate *lsupdate;
u_char *p;
- int num;
+ int lsa_cnt;
struct ospf6_lsa *lsa;
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
@@ -1981,22 +1993,13 @@
return 0;
}
- /* if we have nothing to send, return */
- if (on->lsupdate_list->count == 0 &&
- on->retrans_list->count == 0)
- {
- if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
- zlog_debug ("Quit to send (nothing to send)");
- 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));
- num = 0;
+ lsa_cnt = 0;
/* lsupdate_list lists those LSA which doesn't need to be
retransmitted. remove those from the list */
@@ -2005,58 +2008,85 @@
{
/* MTU check */
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
- > ospf6_packet_max(on->ospf6_if))
- {
- ospf6_lsa_unlock (lsa);
- break;
- }
+ > ospf6_packet_max(on->ospf6_if))
+ {
+ ospf6_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);
- num++;
+ 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 (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
lsa = ospf6_lsdb_next (lsa))
{
/* MTU check */
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
- > ospf6_packet_max(on->ospf6_if))
- {
- ospf6_lsa_unlock (lsa);
- break;
- }
+ > ospf6_packet_max(on->ospf6_if))
+ {
+ ospf6_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);
- num++;
+ lsa_cnt++;
}
- lsupdate->lsa_number = htonl (num);
-
- oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
- oh->length = htons (p - sendbuf);
-
- ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
- on->ospf6_if, oh);
-
- if (on->lsupdate_list->count != 0 ||
- on->retrans_list->count != 0)
+ if (lsa_cnt)
{
- if (on->lsupdate_list->count != 0)
- on->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
+ 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
- on->thread_send_lsupdate =
- thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
- on->ospf6_if->rxmt_interval);
+ ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+ on->ospf6_if, oh);
}
+ if (on->lsupdate_list->count != 0)
+ on->thread_send_lsupdate =
+ thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
+ else if (on->retrans_list->count != 0)
+ on->thread_send_lsupdate =
+ thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
+ on->ospf6_if->rxmt_interval);
return 0;
}
@@ -2067,7 +2097,7 @@
struct ospf6_header *oh;
struct ospf6_lsupdate *lsupdate;
u_char *p;
- int num;
+ int lsa_cnt;
struct ospf6_lsa *lsa;
oi = (struct ospf6_interface *) THREAD_ARG (thread);
@@ -2088,41 +2118,46 @@
memset (sendbuf, 0, iobuflen);
oh = (struct ospf6_header *) sendbuf;
lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
- sizeof (struct ospf6_header));
+ sizeof (struct ospf6_header));
p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
- num = 0;
+ lsa_cnt = 0;
for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
lsa = ospf6_lsdb_next (lsa))
{
/* MTU check */
if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
- > ospf6_packet_max(oi))
- {
- ospf6_lsa_unlock (lsa);
- break;
- }
+ > ospf6_packet_max(oi))
+ {
+ ospf6_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);
- num++;
+ lsa_cnt++;
assert (lsa->lock == 2);
ospf6_lsdb_remove (lsa, oi->lsupdate_list);
}
- lsupdate->lsa_number = htonl (num);
+ if (lsa_cnt)
+ {
+ lsupdate->lsa_number = htonl (lsa_cnt);
- oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
- oh->length = htons (p - sendbuf);
+ oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
+ oh->length = htons (p - sendbuf);
- if (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->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)
{
@@ -2140,6 +2175,7 @@
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;
@@ -2166,16 +2202,16 @@
{
/* 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);
- on->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
+ {
+ /* if we run out of packet size/space here,
+ better to try again soon. */
+ THREAD_OFF (on->thread_send_lsack);
+ on->thread_send_lsack =
+ thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
- ospf6_lsa_unlock (lsa);
- break;
- }
+ ospf6_lsa_unlock (lsa);
+ break;
+ }
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
@@ -2183,13 +2219,24 @@
assert (lsa->lock == 2);
ospf6_lsdb_remove (lsa, on->lsack_list);
+ lsa_cnt++;
}
- oh->type = OSPF6_MESSAGE_TYPE_LSACK;
- oh->length = htons (p - sendbuf);
+ 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);
+ ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+ on->ospf6_if, oh);
+ }
+
+ if (on->thread_send_lsack == NULL && on->lsack_list->count > 0)
+ {
+ on->thread_send_lsack =
+ thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
+ }
+
return 0;
}
@@ -2200,6 +2247,7 @@
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;
@@ -2226,16 +2274,16 @@
{
/* 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);
- oi->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
+ {
+ /* if we run out of packet size/space here,
+ better to try again soon. */
+ THREAD_OFF (oi->thread_send_lsack);
+ oi->thread_send_lsack =
+ thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
- ospf6_lsa_unlock (lsa);
- break;
- }
+ ospf6_lsa_unlock (lsa);
+ break;
+ }
ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
@@ -2243,16 +2291,21 @@
assert (lsa->lock == 2);
ospf6_lsdb_remove (lsa, oi->lsack_list);
+ lsa_cnt++;
}
- oh->type = OSPF6_MESSAGE_TYPE_LSACK;
- oh->length = htons (p - sendbuf);
+ if (lsa_cnt)
+ {
+ oh->type = OSPF6_MESSAGE_TYPE_LSACK;
+ oh->length = htons (p - sendbuf);
- if (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->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->thread_send_lsack == NULL && oi->lsack_list->count > 0)
{