summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_message.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2021-07-27 17:31:34 +0200
committerAdriano Marto Reis <adrianomarto@gmail.com>2023-10-10 08:07:52 +1000
commit0c58d8368878f70dd23a566aaf96d3fcccbc5782 (patch)
tree22066613b81f01891ada8225de6f49226ad5ee59 /ospf6d/ospf6_message.c
parent3d1482a9451039d94dce91f25dac8334354e1f92 (diff)
ospf6d: support unicast hellos on PtP/PtMP
Some lower layers still don't handle multicast correctly (or efficiently.) Add option to send unicast hellos on explicitly configured neighbors for PtP/PtMP. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'ospf6d/ospf6_message.c')
-rw-r--r--ospf6d/ospf6_message.c62
1 files changed, 50 insertions, 12 deletions
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index f7b1bf3b04..244cbe2418 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -268,6 +268,18 @@ static struct ospf6_packet *ospf6_packet_new(size_t size)
return new;
}
+static struct ospf6_packet *ospf6_packet_dup(struct ospf6_packet *old)
+{
+ struct ospf6_packet *new;
+
+ new = XCALLOC(MTYPE_OSPF6_PACKET, sizeof(struct ospf6_packet));
+ new->s = stream_dup(old->s);
+ new->dst = old->dst;
+ new->length = old->length;
+
+ return new;
+}
+
static void ospf6_packet_free(struct ospf6_packet *op)
{
if (op->s)
@@ -2257,8 +2269,6 @@ static void ospf6_write(struct event *thread)
void ospf6_hello_send(struct event *thread)
{
struct ospf6_interface *oi;
- struct ospf6_packet *op;
- uint16_t length = OSPF6_HEADER_SIZE;
oi = (struct ospf6_interface *)EVENT_ARG(thread);
@@ -2287,9 +2297,16 @@ void ospf6_hello_send(struct event *thread)
event_add_timer(master, ospf6_hello_send, oi, oi->hello_interval,
&oi->thread_send_hello);
- if (oi->state == OSPF6_INTERFACE_POINTTOPOINT
- && oi->p2xp_no_multicast_hello)
- return 0;
+ ospf6_hello_send_addr(oi, NULL);
+}
+
+/* used to send polls for PtP/PtMP too */
+void ospf6_hello_send_addr(struct ospf6_interface *oi,
+ const struct in6_addr *addr)
+{
+ struct ospf6_packet *op;
+ uint16_t length = OSPF6_HEADER_SIZE;
+ bool anything = false;
op = ospf6_packet_new(oi->ifmtu);
@@ -2309,16 +2326,37 @@ void ospf6_hello_send(struct event *thread)
/* Set packet length. */
op->length = length;
- op->dst = allspfrouters6;
+ if (!addr && oi->state == OSPF6_INTERFACE_POINTTOPOINT
+ && oi->p2xp_no_multicast_hello) {
+ struct listnode *node;
+ struct ospf6_neighbor *on;
+ struct ospf6_packet *opdup;
- ospf6_fill_hdr_checksum(oi, op);
+ for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) {
+ if (on->state < OSPF6_NEIGHBOR_INIT)
+ /* poll-interval for these */
+ continue;
- /* Add packet to the top of the interface output queue, so that they
- * can't get delayed by things like long queues of LS Update packets
- */
- ospf6_packet_add_top(oi, op);
+ opdup = ospf6_packet_dup(op);
+ opdup->dst = on->linklocal_addr;
+ ospf6_packet_add_top(oi, opdup);
+ anything = true;
+ }
- OSPF6_MESSAGE_WRITE_ON(oi);
+ ospf6_packet_free(op);
+ } else {
+ op->dst = addr ? *addr : allspfrouters6;
+
+ /* Add packet to the top of the interface output queue, so that
+ * they can't get delayed by things like long queues of LS
+ * Update packets
+ */
+ ospf6_packet_add_top(oi, op);
+ anything = true;
+ }
+
+ if (anything)
+ OSPF6_MESSAGE_WRITE_ON(oi);
}
static uint16_t ospf6_make_dbdesc(struct ospf6_neighbor *on, struct stream *s)