From: Yu Watanabe Date: Fri, 17 Nov 2023 20:25:08 +0000 (+0900) Subject: libsystemd-network: introduce triple_timestamp_from_cmsg() X-Git-Tag: v255-rc3~33 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dd59d5e57c62dfb1a0dec68bf16e0bf916f2f714;p=thirdparty%2Fsystemd.git libsystemd-network: introduce triple_timestamp_from_cmsg() Follow-up for 461ef3981f1a45150b6e2047bb3c789ac50ba3cf. This should fix compile error on x32 and riscv32. --- diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c index 25fd70b1b1b..72c20baadc8 100644 --- a/src/libsystemd-network/icmp6-util.c +++ b/src/libsystemd-network/icmp6-util.c @@ -18,6 +18,7 @@ #include "icmp6-util.h" #include "in-addr-util.h" #include "iovec-util.h" +#include "network-common.h" #include "socket-util.h" #define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \ @@ -164,9 +165,7 @@ int icmp6_receive( .msg_control = &control, .msg_controllen = sizeof(control), }; - struct cmsghdr *cmsg; struct in6_addr addr = {}; - triple_timestamp t = {}; ssize_t len; iov = IOVEC_MAKE(buffer, size); @@ -192,31 +191,12 @@ int icmp6_receive( assert(!(msg.msg_flags & MSG_TRUNC)); - CMSG_FOREACH(cmsg, &msg) { - if (cmsg->cmsg_level == SOL_IPV6 && - cmsg->cmsg_type == IPV6_HOPLIMIT && - cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { - int hops = *CMSG_TYPED_DATA(cmsg, int); - - if (hops != 255) - return -EMULTIHOP; - } - - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_TIMESTAMP && - cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) { - struct timeval *tv = memcpy(&(struct timeval) {}, CMSG_DATA(cmsg), sizeof(struct timeval)); - triple_timestamp_from_realtime(&t, timeval_load(tv)); - } - } - - if (ret_timestamp) { - if (triple_timestamp_is_set(&t)) - *ret_timestamp = t; - else - triple_timestamp_now(ret_timestamp); - } + int *hops = CMSG_FIND_DATA(&msg, SOL_IPV6, IPV6_HOPLIMIT, int); + if (hops && *hops != 255) + return -EMULTIHOP; + if (ret_timestamp) + triple_timestamp_from_cmsg(ret_timestamp, &msg); if (ret_sender) *ret_sender = addr; return 0; diff --git a/src/libsystemd-network/network-common.c b/src/libsystemd-network/network-common.c index b23cb8c3533..b639e9ca5a2 100644 --- a/src/libsystemd-network/network-common.c +++ b/src/libsystemd-network/network-common.c @@ -3,6 +3,7 @@ #include "env-util.h" #include "format-util.h" #include "network-common.h" +#include "socket-util.h" #include "unaligned.h" int get_ifname(int ifindex, char **ifname) { @@ -112,3 +113,14 @@ bool network_test_mode_enabled(void) { return test_mode; } + +triple_timestamp* triple_timestamp_from_cmsg(triple_timestamp *t, struct msghdr *mh) { + assert(t); + assert(mh); + + struct timeval *tv = CMSG_FIND_AND_COPY_DATA(mh, SOL_SOCKET, SCM_TIMESTAMP, struct timeval); + if (tv) + return triple_timestamp_from_realtime(t, timeval_load(tv)); + + return triple_timestamp_now(t); +} diff --git a/src/libsystemd-network/network-common.h b/src/libsystemd-network/network-common.h index f71da63b786..1750f1810bd 100644 --- a/src/libsystemd-network/network-common.h +++ b/src/libsystemd-network/network-common.h @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include + #include "log-link.h" #include "sparse-endian.h" #include "time-util.h" @@ -41,3 +43,7 @@ be16_t usec_to_be16_sec(usec_t t); usec_t time_span_to_stamp(usec_t span, usec_t base); bool network_test_mode_enabled(void); + +triple_timestamp* triple_timestamp_from_cmsg(triple_timestamp *t, struct msghdr *mh); +#define TRIPLE_TIMESTAMP_FROM_CMSG(mh) \ + triple_timestamp_from_cmsg(&(triple_timestamp) {}, mh) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 0993c20afd5..67911a2b93a 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -2067,6 +2067,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, s assert(client); assert(message); + assert(timestamp); if (client_verify_message_header(client, message, len) < 0) return 0; @@ -2144,7 +2145,6 @@ static int client_receive_message_udp( .msg_control = &control, .msg_controllen = sizeof(control), }; - triple_timestamp t = {}; int r; assert(s); @@ -2171,12 +2171,8 @@ static int client_receive_message_udp( return 0; } - struct timeval *tv = CMSG_FIND_AND_COPY_DATA(&msg, SOL_SOCKET, SCM_TIMESTAMP, struct timeval); - if (tv) - triple_timestamp_from_realtime(&t, timeval_load(tv)); - log_dhcp_client(client, "Received message from UDP socket, processing."); - r = client_handle_message(client, message, len, &t); + r = client_handle_message(client, message, len, TRIPLE_TIMESTAMP_FROM_CMSG(&msg)); if (r < 0) client_stop(client, r); @@ -2202,7 +2198,6 @@ static int client_receive_message_raw( .msg_controllen = sizeof(control), }; bool checksum = true; - triple_timestamp t = {}; ssize_t buflen, len; int r; @@ -2230,21 +2225,17 @@ static int client_receive_message_raw( return 0; } - struct tpacket_auxdata *aux = CMSG_FIND_AND_COPY_DATA(&msg, SOL_PACKET, PACKET_AUXDATA, struct tpacket_auxdata); + struct tpacket_auxdata *aux = CMSG_FIND_DATA(&msg, SOL_PACKET, PACKET_AUXDATA, struct tpacket_auxdata); if (aux) checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY); - struct timeval *tv = CMSG_FIND_AND_COPY_DATA(&msg, SOL_SOCKET, SCM_TIMESTAMP, struct timeval); - if (tv) - triple_timestamp_from_realtime(&t, timeval_load(tv)); - if (dhcp_packet_verify_headers(packet, len, checksum, client->port) < 0) return 0; len -= DHCP_IP_UDP_SIZE; log_dhcp_client(client, "Received message from RAW socket, processing."); - r = client_handle_message(client, &packet->dhcp, len, &t); + r = client_handle_message(client, &packet->dhcp, len, TRIPLE_TIMESTAMP_FROM_CMSG(&msg)); if (r < 0) client_stop(client, r); diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index ce576c24eb5..fcc5b74364e 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -1391,8 +1391,6 @@ static int server_receive_message(sd_event_source *s, int fd, .msg_controllen = sizeof(control), }; ssize_t datagram_size, len; - struct cmsghdr *cmsg; - triple_timestamp t = {}; int r; datagram_size = next_datagram_size_fd(fd); @@ -1426,22 +1424,16 @@ static int server_receive_message(sd_event_source *s, int fd, return 0; /* TODO figure out if this can be done as a filter on the socket, like for IPv6 */ - CMSG_FOREACH(cmsg, &msg) - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { - struct in_pktinfo *info = CMSG_TYPED_DATA(cmsg, struct in_pktinfo); - if (info->ipi_ifindex != server->ifindex) - return 0; - } else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP) { - struct timeval *tv = CMSG_TYPED_DATA(cmsg, struct timeval); - triple_timestamp_from_realtime(&t, timeval_load(tv)); - } + struct in_pktinfo *info = CMSG_FIND_DATA(&msg, IPPROTO_IP, IP_PKTINFO, struct in_pktinfo); + if (info && info->ipi_ifindex != server->ifindex) + return 0; if (sd_dhcp_server_is_in_relay_mode(server)) { r = dhcp_server_relay_message(server, message, len - sizeof(DHCPMessage), buflen); if (r < 0) log_dhcp_server_errno(server, r, "Couldn't relay message, ignoring: %m"); } else { - r = dhcp_server_handle_message(server, message, (size_t) len, &t); + r = dhcp_server_handle_message(server, message, (size_t) len, TRIPLE_TIMESTAMP_FROM_CMSG(&msg)); if (r < 0) log_dhcp_server_errno(server, r, "Couldn't process incoming message, ignoring: %m"); } diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index c339dfbec2e..c20367dfc95 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -1310,7 +1310,7 @@ static int client_receive_message( .msg_control = &control, .msg_controllen = sizeof(control), }; - triple_timestamp t = {}; + triple_timestamp t; _cleanup_free_ DHCP6Message *message = NULL; struct in6_addr *server_address = NULL; ssize_t buflen, len; @@ -1351,9 +1351,7 @@ static int client_receive_message( server_address = &sa.in6.sin6_addr; } - struct timeval *tv = CMSG_FIND_AND_COPY_DATA(&msg, SOL_SOCKET, SCM_TIMESTAMP, struct timeval); - if (tv) - triple_timestamp_from_realtime(&t, timeval_load(tv)); + triple_timestamp_from_cmsg(&t, &msg); if (client->transaction_id != (message->transaction_id & htobe32(0x00ffffff))) return 0;