diff options
| author | David Lamparter <equinox@opensourcerouting.org> | 2021-07-27 17:31:34 +0200 |
|---|---|---|
| committer | Adriano Marto Reis <adrianomarto@gmail.com> | 2023-10-10 08:07:52 +1000 |
| commit | 0c58d8368878f70dd23a566aaf96d3fcccbc5782 (patch) | |
| tree | 22066613b81f01891ada8225de6f49226ad5ee59 /ospf6d/ospf6_message.c | |
| parent | 3d1482a9451039d94dce91f25dac8334354e1f92 (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.c | 62 |
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) |
