On Wed, Jan 06, 2021 at 01:02:50PM +0100, Claudio Jeker wrote: > 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.
So this seems to work. Anyone wants to OK else I will commit this later today. > -- > :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); >