The code in ospf6d is a bit broken when it comes to point-to-point links. This diff fixes this by a) using the neighbor address instead of the unset interface destination address and by b) matching the incomming packet against all possible IPs of that interface.
I tripped on b) because my P2P interface has more than one link-local address and the code just likes to select the wrong one. This works for my case, please check I did not break something else. -- :wq Claudio Index: lsupdate.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/lsupdate.c,v retrieving revision 1.18 diff -u -p -r1.18 lsupdate.c --- lsupdate.c 15 Jul 2020 14:47:41 -0000 1.18 +++ lsupdate.c 6 Jan 2021 11:28:43 -0000 @@ -474,7 +474,7 @@ ls_retrans_timer(int fd, short event, vo /* ls_retrans_list_free retriggers the timer */ return; } else if (nbr->iface->type == IF_TYPE_POINTOPOINT) - memcpy(&addr, &nbr->iface->dst, sizeof(addr)); + memcpy(&addr, &nbr->addr, sizeof(addr)); else inet_pton(AF_INET6, AllDRouters, &addr); } else Index: packet.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/packet.c,v retrieving revision 1.17 diff -u -p -r1.17 packet.c --- packet.c 23 Dec 2019 07:33:49 -0000 1.17 +++ packet.c 6 Jan 2021 11:52:08 -0000 @@ -82,12 +82,9 @@ send_packet(struct iface *iface, struct struct in6_addr *dst) { struct sockaddr_in6 sa6; - struct msghdr msg; - struct iovec iov[1]; - /* setup buffer */ + /* setup sockaddr */ bzero(&sa6, sizeof(sa6)); - sa6.sin6_family = AF_INET6; sa6.sin6_len = sizeof(sa6); sa6.sin6_addr = *dst; @@ -104,15 +101,8 @@ send_packet(struct iface *iface, struct return (-1); } - bzero(&msg, sizeof(msg)); - msg.msg_name = &sa6; - msg.msg_namelen = sizeof(sa6); - iov[0].iov_base = buf->buf; - iov[0].iov_len = ibuf_size(buf); - msg.msg_iov = iov; - msg.msg_iovlen = 1; - - if (sendmsg(iface->fd, &msg, 0) == -1) { + if (sendto(iface->fd, buf->buf, ibuf_size(buf), 0, + (struct sockaddr *)&sa6, sizeof(sa6)) == -1) { log_warn("send_packet: error sending packet on interface %s", iface->name); return (-1); @@ -186,11 +176,16 @@ recv_packet(int fd, short event, void *b * AllDRouters is only valid for DR and BDR but this is checked later. */ inet_pton(AF_INET6, AllSPFRouters, &addr); - if (!IN6_ARE_ADDR_EQUAL(&dest, &addr)) { inet_pton(AF_INET6, AllDRouters, &addr); if (!IN6_ARE_ADDR_EQUAL(&dest, &addr)) { - if (!IN6_ARE_ADDR_EQUAL(&dest, &iface->addr)) { + struct iface_addr *ia; + + TAILQ_FOREACH(ia, &iface->ifa_list, entry) { + if (IN6_ARE_ADDR_EQUAL(&dest, &ia->addr)) + break; + } + if (ia == NULL) { log_debug("recv_packet: packet sent to wrong " "address %s, interface %s", log_in6addr(&dest), iface->name);