ntp: add interface index to NTP_Local_Address

This will allow us to get the interface index when sending responses to
clients.
This commit is contained in:
Miroslav Lichvar 2017-01-20 10:42:19 +01:00
parent a60fc73e7b
commit 86acea5c46
6 changed files with 22 additions and 15 deletions

View file

@ -50,8 +50,11 @@ typedef struct {
unsigned short port; unsigned short port;
} NTP_Remote_Address; } NTP_Remote_Address;
#define INVALID_IF_INDEX -1
typedef struct { typedef struct {
IPAddr ip_addr; IPAddr ip_addr;
int if_index;
int sock_fd; int sock_fd;
} NTP_Local_Address; } NTP_Local_Address;

View file

@ -482,6 +482,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
result->remote_addr = *remote_addr; result->remote_addr = *remote_addr;
result->local_addr.ip_addr.family = IPADDR_UNSPEC; result->local_addr.ip_addr.family = IPADDR_UNSPEC;
result->local_addr.if_index = INVALID_IF_INDEX;
switch (type) { switch (type) {
case NTP_SERVER: case NTP_SERVER:
@ -665,6 +666,7 @@ NCR_ChangeRemoteAddress(NCR_Instance inst, NTP_Remote_Address *remote_addr)
else { else {
NIO_CloseServerSocket(inst->local_addr.sock_fd); NIO_CloseServerSocket(inst->local_addr.sock_fd);
inst->local_addr.ip_addr.family = IPADDR_UNSPEC; inst->local_addr.ip_addr.family = IPADDR_UNSPEC;
inst->local_addr.if_index = INVALID_IF_INDEX;
inst->local_addr.sock_fd = NIO_OpenServerSocket(remote_addr); inst->local_addr.sock_fd = NIO_OpenServerSocket(remote_addr);
} }
@ -1094,6 +1096,7 @@ transmit_timeout(void *arg)
/* Don't require the packet to be sent from the same address as before */ /* Don't require the packet to be sent from the same address as before */
local_addr.ip_addr.family = IPADDR_UNSPEC; local_addr.ip_addr.family = IPADDR_UNSPEC;
local_addr.if_index = INVALID_IF_INDEX;
local_addr.sock_fd = inst->local_addr.sock_fd; local_addr.sock_fd = inst->local_addr.sock_fd;
/* Check whether we need to 'warm up' the link to the other end by /* Check whether we need to 'warm up' the link to the other end by
@ -1627,8 +1630,9 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
server and the socket can be closed */ server and the socket can be closed */
close_client_socket(inst); close_client_socket(inst);
/* Update the local address */ /* Update the local address and interface */
inst->local_addr.ip_addr = local_addr->ip_addr; inst->local_addr.ip_addr = local_addr->ip_addr;
inst->local_addr.if_index = local_addr->if_index;
/* And now, requeue the timer */ /* And now, requeue the timer */
if (inst->opmode != MD_OFFLINE) { if (inst->opmode != MD_OFFLINE) {
@ -2392,6 +2396,7 @@ NCR_AddBroadcastDestination(IPAddr *addr, unsigned short port, int interval)
destination->addr.ip_addr = *addr; destination->addr.ip_addr = *addr;
destination->addr.port = port; destination->addr.port = port;
destination->local_addr.ip_addr.family = IPADDR_UNSPEC; destination->local_addr.ip_addr.family = IPADDR_UNSPEC;
destination->local_addr.if_index = INVALID_IF_INDEX;
destination->local_addr.sock_fd = NIO_OpenServerSocket(&destination->addr); destination->local_addr.sock_fd = NIO_OpenServerSocket(&destination->addr);
destination->interval = CLAMP(1, interval, 1 << MAX_POLL); destination->interval = CLAMP(1, interval, 1 << MAX_POLL);

View file

@ -578,7 +578,6 @@ process_message(struct msghdr *hdr, int length, int sock_fd)
NTP_Local_Timestamp local_ts; NTP_Local_Timestamp local_ts;
struct timespec sched_ts; struct timespec sched_ts;
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
int if_index;
SCH_GetLastEventTime(&local_ts.ts, &local_ts.err, NULL); SCH_GetLastEventTime(&local_ts.ts, &local_ts.err, NULL);
local_ts.source = NTP_TS_DAEMON; local_ts.source = NTP_TS_DAEMON;
@ -598,8 +597,8 @@ process_message(struct msghdr *hdr, int length, int sock_fd)
} }
local_addr.ip_addr.family = IPADDR_UNSPEC; local_addr.ip_addr.family = IPADDR_UNSPEC;
local_addr.if_index = INVALID_IF_INDEX;
local_addr.sock_fd = sock_fd; local_addr.sock_fd = sock_fd;
if_index = -1;
if (hdr->msg_flags & MSG_TRUNC) { if (hdr->msg_flags & MSG_TRUNC) {
DEBUG_LOG(LOGF_NtpIO, "Received truncated message from %s:%d", DEBUG_LOG(LOGF_NtpIO, "Received truncated message from %s:%d",
@ -620,7 +619,7 @@ process_message(struct msghdr *hdr, int length, int sock_fd)
memcpy(&ipi, CMSG_DATA(cmsg), sizeof(ipi)); memcpy(&ipi, CMSG_DATA(cmsg), sizeof(ipi));
local_addr.ip_addr.addr.in4 = ntohl(ipi.ipi_addr.s_addr); local_addr.ip_addr.addr.in4 = ntohl(ipi.ipi_addr.s_addr);
local_addr.ip_addr.family = IPADDR_INET4; local_addr.ip_addr.family = IPADDR_INET4;
if_index = ipi.ipi_ifindex; local_addr.if_index = ipi.ipi_ifindex;
} }
#endif #endif
@ -632,7 +631,7 @@ process_message(struct msghdr *hdr, int length, int sock_fd)
memcpy(&local_addr.ip_addr.addr.in6, &ipi.ipi6_addr.s6_addr, memcpy(&local_addr.ip_addr.addr.in6, &ipi.ipi6_addr.s6_addr,
sizeof (local_addr.ip_addr.addr.in6)); sizeof (local_addr.ip_addr.addr.in6));
local_addr.ip_addr.family = IPADDR_INET6; local_addr.ip_addr.family = IPADDR_INET6;
if_index = ipi.ipi6_ifindex; local_addr.if_index = ipi.ipi6_ifindex;
} }
#endif #endif
@ -660,14 +659,13 @@ process_message(struct msghdr *hdr, int length, int sock_fd)
} }
#ifdef HAVE_LINUX_TIMESTAMPING #ifdef HAVE_LINUX_TIMESTAMPING
if (NIO_Linux_ProcessMessage(&remote_addr, &local_addr, &local_ts, if (NIO_Linux_ProcessMessage(&remote_addr, &local_addr, &local_ts, hdr, length))
hdr, length, sock_fd, if_index))
return; return;
#endif #endif
DEBUG_LOG(LOGF_NtpIO, "Received %d bytes from %s:%d to %s fd=%d if=%d tss=%d delay=%.9f", DEBUG_LOG(LOGF_NtpIO, "Received %d bytes from %s:%d to %s fd=%d if=%d tss=%d delay=%.9f",
length, UTI_IPToString(&remote_addr.ip_addr), remote_addr.port, length, UTI_IPToString(&remote_addr.ip_addr), remote_addr.port,
UTI_IPToString(&local_addr.ip_addr), local_addr.sock_fd, if_index, UTI_IPToString(&local_addr.ip_addr), local_addr.sock_fd, local_addr.if_index,
local_ts.source, UTI_DiffTimespecsToDouble(&sched_ts, &local_ts.ts)); local_ts.source, UTI_DiffTimespecsToDouble(&sched_ts, &local_ts.ts));
/* Just ignore the packet if it's not of a recognized length */ /* Just ignore the packet if it's not of a recognized length */

View file

@ -480,8 +480,7 @@ extract_udp_data(unsigned char *msg, NTP_Remote_Address *remote_addr, int len)
int int
NIO_Linux_ProcessMessage(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, NIO_Linux_ProcessMessage(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
NTP_Local_Timestamp *local_ts, struct msghdr *hdr, NTP_Local_Timestamp *local_ts, struct msghdr *hdr, int length)
int length, int sock_fd, int if_index)
{ {
struct Interface *iface; struct Interface *iface;
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
@ -500,12 +499,13 @@ NIO_Linux_ProcessMessage(NTP_Remote_Address *remote_addr, NTP_Local_Address *loc
LCL_CookTime(&ts3.ts[0], &local_ts->ts, &local_ts->err); LCL_CookTime(&ts3.ts[0], &local_ts->ts, &local_ts->err);
local_ts->source = NTP_TS_KERNEL; local_ts->source = NTP_TS_KERNEL;
} else if (!UTI_IsZeroTimespec(&ts3.ts[2])) { } else if (!UTI_IsZeroTimespec(&ts3.ts[2])) {
iface = get_interface(if_index); iface = get_interface(local_addr->if_index);
if (iface) { if (iface) {
process_hw_timestamp(iface, &ts3.ts[2], local_ts, !is_tx ? length : 0, process_hw_timestamp(iface, &ts3.ts[2], local_ts, !is_tx ? length : 0,
remote_addr->ip_addr.family); remote_addr->ip_addr.family);
} else { } else {
DEBUG_LOG(LOGF_NtpIOLinux, "HW clock not found for interface %d", if_index); DEBUG_LOG(LOGF_NtpIOLinux, "HW clock not found for interface %d",
local_addr->if_index);
} }
} }
} }
@ -537,7 +537,7 @@ NIO_Linux_ProcessMessage(NTP_Remote_Address *remote_addr, NTP_Local_Address *loc
DEBUG_LOG(LOGF_NtpIOLinux, "Received %d (%d) bytes from error queue for %s:%d fd=%d if=%d tss=%d", DEBUG_LOG(LOGF_NtpIOLinux, "Received %d (%d) bytes from error queue for %s:%d fd=%d if=%d tss=%d",
l2_length, length, UTI_IPToString(&remote_addr->ip_addr), remote_addr->port, l2_length, length, UTI_IPToString(&remote_addr->ip_addr), remote_addr->port,
sock_fd, if_index, local_ts->source); local_addr->sock_fd, local_addr->if_index, local_ts->source);
/* Update assumed position of UDP data at layer 2 for next received packet */ /* Update assumed position of UDP data at layer 2 for next received packet */
if (iface && length) { if (iface && length) {

View file

@ -31,7 +31,6 @@ extern void NIO_Linux_Finalise(void);
extern int NIO_Linux_SetTimestampSocketOptions(int sock_fd, int client_only, int *events); extern int NIO_Linux_SetTimestampSocketOptions(int sock_fd, int client_only, int *events);
extern int NIO_Linux_ProcessMessage(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, extern int NIO_Linux_ProcessMessage(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
NTP_Local_Timestamp *local_ts, struct msghdr *hdr, int length, NTP_Local_Timestamp *local_ts, struct msghdr *hdr, int length);
int sock_fd, int if_index);
extern int NIO_Linux_RequestTxTimestamp(struct msghdr *msg, int cmsglen, int sock_fd); extern int NIO_Linux_RequestTxTimestamp(struct msghdr *msg, int cmsglen, int sock_fd);

View file

@ -80,6 +80,7 @@ send_request(void)
advance_time(1e-4); advance_time(1e-4);
local_addr.ip_addr.family = IPADDR_UNSPEC; local_addr.ip_addr.family = IPADDR_UNSPEC;
local_addr.if_index = INVALID_IF_INDEX;
local_addr.sock_fd = 101; local_addr.sock_fd = 101;
local_ts.ts = current_time; local_ts.ts = current_time;
local_ts.err = 0.0; local_ts.err = 0.0;
@ -176,6 +177,7 @@ process_response(int valid, int updated)
res = &res_buffer.ntp_pkt; res = &res_buffer.ntp_pkt;
local_addr.ip_addr.family = IPADDR_UNSPEC; local_addr.ip_addr.family = IPADDR_UNSPEC;
local_addr.if_index = INVALID_IF_INDEX;
local_addr.sock_fd = NTP_LVM_TO_MODE(res->lvm) == MODE_ACTIVE ? 100 : 101; local_addr.sock_fd = NTP_LVM_TO_MODE(res->lvm) == MODE_ACTIVE ? 100 : 101;
local_ts.ts = current_time; local_ts.ts = current_time;
local_ts.err = 0.0; local_ts.err = 0.0;