Created attachment 6591 [details] busybox config When sending NTP queries to a secondary IP addresses of a device running busybox ntpd, the replies are sent from the primary IP address. This happens for both IPv4 and IPv6. Interface addresses: 15: eth0.54@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 04:18:d6:31:38:b3 brd ff:ff:ff:ff:ff:ff inet 192.168.54.254/24 brd 192.168.54.255 scope global eth0.54 valid_lft forever preferred_lft forever inet 192.168.54.1/24 brd 192.168.54.255 scope global secondary eth0.54 valid_lft forever preferred_lft forever inet6 [hidden]/64 scope global noprefixroute valid_lft forever preferred_lft forever inet6 fe80::1/64 scope link nodad valid_lft forever preferred_lft forever inet6 fe80::618:d6ff:fe31:38b3/64 scope link valid_lft forever preferred_lft forever IPv4 tcpdump: 11:15:22.468631 IP 192.168.54.121.123 > 192.168.54.1.123: NTPv4, Client, length 48 11:15:22.469272 IP 192.168.54.254.123 > 192.168.54.121.123: NTPv4, Server, length 48 11:15:24.468616 IP 192.168.54.121.123 > 192.168.54.1.123: NTPv4, Client, length 48 11:15:24.469014 IP 192.168.54.254.123 > 192.168.54.121.123: NTPv4, Server, length 48 11:15:26.468606 IP 192.168.54.121.123 > 192.168.54.1.123: NTPv4, Client, length 48 11:15:26.468999 IP 192.168.54.254.123 > 192.168.54.121.123: NTPv4, Server, length 48 11:15:28.468622 IP 192.168.54.121.123 > 192.168.54.1.123: NTPv4, Client, length 48 11:15:28.469010 IP 192.168.54.254.123 > 192.168.54.121.123: NTPv4, Server, length 48 Result on the client: 8 Aug 11:15:30 ntpdate[13088]: no server suitable for synchronization found IPv6 tcpdump: 11:17:48.020528 IP6 fe80::be5f:f4ff:fe67:1f9a.123 > fe80::618:d6ff:fe31:38b3.123: NTPv4, Client, length 48 11:17:48.021053 IP6 fe80::1.123 > fe80::be5f:f4ff:fe67:1f9a.123: NTPv4, Server, length 48 11:17:50.020552 IP6 fe80::be5f:f4ff:fe67:1f9a.123 > fe80::618:d6ff:fe31:38b3.123: NTPv4, Client, length 48 11:17:50.020989 IP6 fe80::1.123 > fe80::be5f:f4ff:fe67:1f9a.123: NTPv4, Server, length 48 11:17:52.020525 IP6 fe80::be5f:f4ff:fe67:1f9a.123 > fe80::618:d6ff:fe31:38b3.123: NTPv4, Client, length 48 11:17:52.020963 IP6 fe80::1.123 > fe80::be5f:f4ff:fe67:1f9a.123: NTPv4, Server, length 48 11:17:54.020563 IP6 fe80::be5f:f4ff:fe67:1f9a.123 > fe80::618:d6ff:fe31:38b3.123: NTPv4, Client, length 48 11:17:54.021004 IP6 fe80::1.123 > fe80::be5f:f4ff:fe67:1f9a.123: NTPv4, Server, length 48 Result on the client: 8 Aug 11:17:56 ntpdate[13099]: no server suitable for synchronization found
Also reported on the OpenWrt bug tracker: https://dev.openwrt.org/ticket/18404 https://dev.openwrt.org/ticket/22976
Please check that the libc you compile against provides IP_PKTINFO. Specifically, this ifndef in udp_io.c should not be taken: ssize_t FAST_FUNC send_to_from(int fd, void *buf, size_t len, int flags, const struct sockaddr *to, const struct sockaddr *from, socklen_t tolen) { #ifndef IP_PKTINFO (void)from; /* suppress "unused from" warning */ return sendto(fd, buf, len, flags, to, tolen); #else If you are sure that the "else" branch is taken here, then please strace your ntpd invocation, *from the beginning* (not strace -p PID) and attach the log here.
This is on LEDE, currently using musl libc v1.1.15. It provides IP_PKTINFO in netinet/in.h [1], which is only included on FreeBSD, OpenBSD and Apple. It also happened a on OpenWrt at the time it was still using uClibc by default. In uClibc, IP_PKTINFO is defined in https://git.uclibc.org/uClibc/tree/libc/sysdeps/linux/common/bits/in.h Is this something you are willing to fix, or do we need to patch it in LEDE? [1] http://git.musl-libc.org/cgit/musl/tree/include/netinet/in.h?h=v1.1.15&id=faf69b9a73d09fafcbe4fd3007b8d8724293d8e1#n182
(In reply to Stijn Tintel from comment #3) > It also happened a on OpenWrt at the time it was still using uClibc by default. In uClibc, IP_PKTINFO is defined in https://git.uclibc.org/uClibc/tree/libc/sysdeps/linux/common/bits/in.h On uclibc, IP_PKTINFO is successfully picked up. At least for me. > Is this something you are willing to fix, or do we need to patch it in LEDE? Please let me know which modification of includes in ntpd.c makes your build against musl work? Currently it has #include "libbb.h" #include <math.h> #include <netinet/ip.h> /* For IPTOS_LOWDELAY definition */ #include <sys/resource.h> /* setpriority */ #include <sys/timex.h>
(In reply to Denys Vlasenko from comment #4) Turns out this isn't related to missing includes, or IP_PKTINFO not being defined. For IPv4, the problem seems to be that to->sa_family is AF_INET6 instead of AF_INET4. With this change in send_to_from() in libbb/udp_io.c, it works fine: @@ -70,7 +71,7 @@ send_to_from(int fd, void *buf, size_t l msg.msg_flags = flags; cmsgptr = CMSG_FIRSTHDR(&msg); - if (to->sa_family == AF_INET && from->sa_family == AF_INET) { + if (from->sa_family == AF_INET) { struct in_pktinfo *pktptr; cmsgptr->cmsg_level = IPPROTO_IP; cmsgptr->cmsg_type = IP_PKTINFO; For IPv6, both to->sa_family and from->sa_family are AF_INET6. I'll need to debug this further, but that'll be for another day.
Fixed in git, thanks!