From: Frank Kardel Date: Sun, 11 Jan 2009 16:53:36 +0000 (+0000) Subject: ChangeLog: X-Git-Tag: NTP_4_2_5P154~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9cbdfd7914361d1beb604d1827d976d4150f35b0;p=thirdparty%2Fntp.git ChangeLog: bug 992 - support interface event change on Linux configure.ac, ntp_io.c: support interface event change on Linux bk: 496a2410i5F02lfaOF9ZgVXzsgOlWA --- diff --git a/ChangeLog b/ChangeLog index 17a6d110f..7dd7ed3c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +* [Bug 992] support interface event change on Linux from + Miroslav Lichvar. (4.2.5p153) 2009/01/09 Released by Harlan Stenn * Renamed gsoc_sntp/:fetch-stubs to gsoc_sntp/fetch-stubs to avoid file name problems under Windows. diff --git a/configure.ac b/configure.ac index 61018e9fd..041a91acc 100644 --- a/configure.ac +++ b/configure.ac @@ -789,8 +789,20 @@ AC_CACHE_CHECK(for struct rt_msghdr, ac_cv_struct_rt_msghdr, ac_cv_struct_rt_msghdr=yes, ac_cv_struct_rt_msghdr=no) ]) -if test $ac_cv_struct_rt_msghdr = yes; then + +AC_CACHE_CHECK(for struct rtattr, ac_cv_struct_rtattr, +[AC_TRY_COMPILE([ +#include ], +[struct rtattr p;], + ac_cv_struct_rtattr=yes, + ac_cv_struct_rtattr=no) +]) + +if test $ac_cv_struct_rt_msghdr = yes -o $ac_cv_struct_rtattr = yes; then AC_DEFINE(HAS_ROUTING_SOCKET, 1, [Do we have a routing socket (struct rt_msghdr)?]) + if test $ac_cv_struct_rtattr = yes; then + AC_DEFINE(HAVE_RTNETLINK, 1, [Do we have Linux routing socket?]) + fi fi AC_CACHE_CHECK( diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index b682ffd1e..34892f075 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -3971,6 +3971,10 @@ find_flagged_addr_in_list(struct sockaddr_storage *addr, int flag) { #ifdef HAS_ROUTING_SOCKET #include +#ifdef HAVE_RTNETLINK +#include +#endif + #ifndef UPDATE_GRACE #define UPDATE_GRACE 2 /* wait UPDATE_GRACE seconds before scanning */ #endif @@ -3979,9 +3983,13 @@ static void process_routing_msgs(struct asyncio_reader *reader) { char buffer[5120]; - char *p = buffer; - - int cnt; + int cnt, msg_type; +#ifdef HAVE_RTNETLINK + struct nlmsghdr *nh; +#else + struct rt_msghdr *rtm; + char *p; +#endif if (disable_dynamic_updates) { /* @@ -4005,19 +4013,22 @@ process_routing_msgs(struct asyncio_reader *reader) /* * process routing message */ - while ((p + sizeof(struct rt_msghdr)) <= (buffer + cnt)) - { - struct rt_msghdr *rtm; - +#ifdef HAVE_RTNETLINK + for (nh = (struct nlmsghdr *)buffer; NLMSG_OK(nh, cnt); nh = NLMSG_NEXT(nh, cnt)) { + msg_type = nh->nlmsg_type; +#else + for (p = buffer; (p + sizeof(struct rt_msghdr)) <= (buffer + cnt); p += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)p; if (rtm->rtm_version != RTM_VERSION) { - msyslog(LOG_ERR, "version mismatch on routing socket %m - disabling"); + msyslog(LOG_ERR, "version mismatch (got %d - expected %d) on routing socket - disabling", rtm->rtm_version, RTM_VERSION); + remove_asyncio_reader(reader); delete_asyncio_reader(reader); return; } - - switch (rtm->rtm_type) { + msg_type = rtm->rtm_type; +#endif + switch (msg_type) { #ifdef RTM_NEWADDR case RTM_NEWADDR: #endif @@ -4044,21 +4055,37 @@ process_routing_msgs(struct asyncio_reader *reader) #endif #ifdef RTM_IFANNOUNCE case RTM_IFANNOUNCE: +#endif +#ifdef RTM_NEWLINK + case RTM_NEWLINK: +#endif +#ifdef RTM_DELLINK + case RTM_DELLINK: +#endif +#ifdef RTM_NEWROUTE + case RTM_NEWROUTE: +#endif +#ifdef RTM_DELROUTE + case RTM_DELROUTE: #endif /* * we are keen on new and deleted addresses and if an interface goes up and down or routing changes */ - DPRINTF(3, ("routing message op = %d: scheduling interface update\n", rtm->rtm_type)); + DPRINTF(3, ("routing message op = %d: scheduling interface update\n", msg_type)); timer_interfacetimeout(current_time + UPDATE_GRACE); break; +#ifdef HAVE_RTNETLINK + case NLMSG_DONE: + /* end of multipart message */ + return; +#endif default: /* * the rest doesn't bother us. */ - DPRINTF(4, ("routing message op = %d: ignored\n", rtm->rtm_type)); + DPRINTF(4, ("routing message op = %d: ignored\n", msg_type)); break; } - p += rtm->rtm_msglen; } } @@ -4069,10 +4096,25 @@ static void init_async_notifications() { struct asyncio_reader *reader; +#ifdef HAVE_RTNETLINK + int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + struct sockaddr_nl sa; +#else int fd = socket(PF_ROUTE, SOCK_RAW, 0); +#endif if (fd >= 0) { fd = move_fd(fd); +#ifdef HAVE_RTNETLINK + memset(&sa, 0, sizeof(sa)); + sa.nl_family = PF_NETLINK; + sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | + RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_MROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_MROUTE; + if (bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0) { + msyslog(LOG_ERR, "bind failed on routing socket (%m) - using polled interface update"); + return; + } +#endif init_nonblocking_io(fd); #if defined(HAVE_SIGNALED_IO) init_socket_sig(fd);