From 004845d18ed31fe5ffc153699f63e58dc8b24171 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 15:56:01 +0200 Subject: sd-network: unify packet processing logic a bit Let's always check for errno being EAGAIN/EINTR the same way, and always log if we receive weirdly short packets. --- src/libsystemd-network/dhcp-internal.h | 3 ++- src/libsystemd-network/sd-dhcp-client.c | 6 +++--- src/libsystemd-network/sd-dhcp6-client.c | 12 ++++++++++-- src/libsystemd-network/sd-ipv4acd.c | 3 +++ src/libsystemd-network/sd-ndisc.c | 8 ++++++-- 5 files changed, 24 insertions(+), 8 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h index 4662b0d847..99f690897d 100644 --- a/src/libsystemd-network/dhcp-internal.h +++ b/src/libsystemd-network/dhcp-internal.h @@ -65,4 +65,5 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum); #define DHCP_CLIENT_DONT_DESTROY(client) \ _cleanup_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client) -#define log_dhcp_client(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) +#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) +#define log_dhcp_client(client, fmt, ...) log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index ad79c6cc2c..f0ad9efbc6 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1645,9 +1645,9 @@ static int client_receive_message_udp( if (errno == EAGAIN || errno == EINTR) return 0; - log_dhcp_client(client, "Could not receive message from UDP socket: %m"); - return -errno; - } else if ((size_t)len < sizeof(DHCPMessage)) { + return log_dhcp_client_errno(client, errno, "Could not receive message from UDP socket: %m"); + } + if ((size_t) len < sizeof(DHCPMessage)) { log_dhcp_client(client, "Too small to be a DHCP message: ignoring"); return 0; } diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 05972e01c9..7dead24836 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -898,7 +898,12 @@ static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *adver return r; } -static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) { +static int client_receive_message( + sd_event_source *s, + int fd, uint32_t + revents, + void *userdata) { + sd_dhcp6_client *client = userdata; DHCP6_CLIENT_DONT_DESTROY(client); _cleanup_free_ DHCP6Message *message = NULL; @@ -924,8 +929,11 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m"); - } else if ((size_t)len < sizeof(DHCP6Message)) + } + if ((size_t) len < sizeof(DHCP6Message)) { + log_dhcp6_client(client, "Too small to be DHCP6 message: ignoring"); return 0; + } switch(message->type) { case DHCP6_SOLICIT: diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index c1f43c824b..3c9fa85198 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -366,6 +366,9 @@ static int ipv4acd_on_packet( n = recv(fd, &packet, sizeof(struct ether_arp), 0); if (n < 0) { + if (errno == EAGAIN || errno == EINTR) + return 0; + r = log_ipv4acd_debug_errno(ll, errno, "Failed to read ARP packet: %m"); goto out; } diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index fb4ef55673..8d18707de1 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -517,9 +517,13 @@ static int ndisc_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r log_ndisc(nd, "Could not receive message from ICMPv6 socket: %m"); return -errno; - } else if ((size_t)len < sizeof(struct nd_router_advert)) { + } + if ((size_t) len < sizeof(struct nd_router_advert)) { + log_ndisc(nd, "Too small to be a router advertisement: ignoring"); return 0; - } else if (msg.msg_namelen == 0) + } + + if (msg.msg_namelen == 0) gw = NULL; /* only happens when running the test-suite over a socketpair */ else if (msg.msg_namelen != sizeof(sa.in6)) { log_ndisc(nd, "Received invalid source address size from ICMPv6 socket: %zu bytes", (size_t)msg.msg_namelen); -- cgit v1.2.3-54-g00ecf From 16f0b479cafb745c23efb1a96ccc520fe29e8d7c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 15:57:31 +0200 Subject: sd-dhcp: shorten NUL initialization a bit --- src/libsystemd-network/sd-dhcp-client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index f0ad9efbc6..aa028e1d24 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1624,7 +1624,7 @@ static int client_receive_message_udp( sd_dhcp_client *client = userdata; _cleanup_free_ DHCPMessage *message = NULL; - const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } }; + const struct ether_addr zero_mac = {}; const struct ether_addr *expected_chaddr = NULL; uint8_t expected_hlen = 0; ssize_t len, buflen; -- cgit v1.2.3-54-g00ecf From 9c2438b84e1071a841364250f2dec2b15dafceb7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 15:57:39 +0200 Subject: sd-ndisc: properly make various parameters unsigned --- src/libsystemd-network/sd-ndisc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 8d18707de1..bb62cc21a3 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -34,8 +34,8 @@ #include "socket-util.h" #include "string-util.h" -#define NDISC_ROUTER_SOLICITATION_INTERVAL 4 * USEC_PER_SEC -#define NDISC_MAX_ROUTER_SOLICITATIONS 3 +#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC) +#define NDISC_MAX_ROUTER_SOLICITATIONS 3U enum NDiscState { NDISC_STATE_IDLE, @@ -45,9 +45,9 @@ enum NDiscState { _NDISC_STATE_INVALID = -1, }; -#define IP6_MIN_MTU (unsigned)1280 +#define IP6_MIN_MTU 1280U #define ICMP6_RECV_SIZE (IP6_MIN_MTU - sizeof(struct ip6_hdr)) -#define NDISC_OPT_LEN_UNITS 8 +#define NDISC_OPT_LEN_UNITS 8U #define ND_RA_FLAG_PREF 0x18 #define ND_RA_FLAG_PREF_LOW 0x03 @@ -82,7 +82,7 @@ struct sd_ndisc { int fd; sd_event_source *recv; sd_event_source *timeout; - int nd_sent; + unsigned nd_sent; sd_ndisc_router_callback_t router_callback; sd_ndisc_prefix_autonomous_callback_t prefix_autonomous_callback; sd_ndisc_prefix_onlink_callback_t prefix_onlink_callback; -- cgit v1.2.3-54-g00ecf From 2f8e763376e932395c859d0ab5a8931b7f27fe18 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 16:13:18 +0200 Subject: sd-network: rename "index" field of the various clients to "ifindex" A field "index" is not particularly precise and also might conflict with libc's index() function definition. Also, pretty much everywhere else we call this concept "ifindex", including in networkd, the primary user of these libraries. Hence, let's fix this up and call this "ifindex" everywhere here too. --- src/libsystemd-network/sd-dhcp-client.c | 27 +++++++++++++-------------- src/libsystemd-network/sd-dhcp6-client.c | 27 +++++++++++---------------- src/libsystemd-network/sd-ipv4acd.c | 20 ++++++++++---------- src/libsystemd-network/sd-ipv4ll.c | 5 +++-- src/libsystemd-network/sd-ndisc.c | 17 ++++++++--------- src/libsystemd-network/test-acd.c | 2 +- src/libsystemd-network/test-dhcp-client.c | 16 ++++++++-------- src/libsystemd-network/test-dhcp6-client.c | 10 +++++----- src/libsystemd-network/test-ipv4ll-manual.c | 2 +- src/libsystemd-network/test-ipv4ll.c | 12 ++++++------ src/libsystemd-network/test-ndisc-rs.c | 2 +- src/network/networkd-dhcp4.c | 2 +- src/network/networkd-dhcp6.c | 2 +- src/network/networkd-ipv4ll.c | 2 +- src/network/networkd-ndisc.c | 2 +- src/systemd/sd-dhcp-client.h | 2 +- src/systemd/sd-dhcp6-client.h | 2 +- src/systemd/sd-ipv4acd.h | 2 +- src/systemd/sd-ipv4ll.h | 2 +- src/systemd/sd-ndisc.h | 2 +- 20 files changed, 76 insertions(+), 82 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index aa028e1d24..fab9f3f088 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -53,7 +53,7 @@ struct sd_dhcp_client { sd_event *event; int event_priority; sd_event_source *timeout_resend; - int index; + int ifindex; int fd; union sockaddr_union link; sd_event_source *receive_message; @@ -194,14 +194,13 @@ int sd_dhcp_client_set_request_address( return 0; } -int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) { - assert_return(client, -EINVAL); - assert_return (IN_SET(client->state, DHCP_STATE_INIT, - DHCP_STATE_STOPPED), -EBUSY); - assert_return(interface_index > 0, -EINVAL); +int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) { - client->index = interface_index; + assert_return(client, -EINVAL); + assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY); + assert_return(ifindex > 0, -EINVAL); + client->ifindex = ifindex; return 0; } @@ -348,7 +347,7 @@ int sd_dhcp_client_set_iaid_duid( /* If IAID is not configured, generate it. */ if (iaid == 0) { - r = dhcp_identifier_set_iaid(client->index, client->mac_addr, + r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid); if (r < 0) @@ -565,7 +564,7 @@ static int client_message_init( client->client_id.type = 255; - r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid); + r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid); if (r < 0) return r; @@ -1101,7 +1100,7 @@ static int client_start_delayed(sd_dhcp_client *client) { assert_return(client, -EINVAL); assert_return(client->event, -EINVAL); - assert_return(client->index > 0, -EINVAL); + assert_return(client->ifindex > 0, -EINVAL); assert_return(client->fd < 0, -EBUSY); assert_return(client->xid == 0, -EINVAL); assert_return(client->state == DHCP_STATE_INIT || @@ -1109,7 +1108,7 @@ static int client_start_delayed(sd_dhcp_client *client) { client->xid = random_u32(); - r = dhcp_network_bind_raw_socket(client->index, &client->link, + r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid, client->mac_addr, client->mac_addr_len, client->arp_type); if (r < 0) { @@ -1157,7 +1156,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) client->state = DHCP_STATE_REBINDING; client->attempt = 1; - r = dhcp_network_bind_raw_socket(client->index, &client->link, + r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid, client->mac_addr, client->mac_addr_len, client->arp_type); if (r < 0) { @@ -1778,7 +1777,7 @@ int sd_dhcp_client_start(sd_dhcp_client *client) { r = client_start(client); if (r >= 0) - log_dhcp_client(client, "STARTED on ifindex %i", client->index); + log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex); return r; } @@ -1879,7 +1878,7 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) { client->n_ref = 1; client->state = DHCP_STATE_INIT; - client->index = -1; + client->ifindex = -1; client->fd = -1; client->attempt = 1; client->mtu = DHCP_DEFAULT_MIN_SIZE; diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 7dead24836..15667c26d7 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -45,7 +45,7 @@ struct sd_dhcp6_client { enum DHCP6State state; sd_event *event; int event_priority; - int index; + int ifindex; struct in6_addr local_address; uint8_t mac_addr[MAX_MAC_ADDR_LEN]; size_t mac_addr_len; @@ -123,14 +123,13 @@ int sd_dhcp6_client_set_callback( return 0; } -int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) { - assert_return(client, -EINVAL); - assert_return(interface_index >= -1, -EINVAL); +int sd_dhcp6_client_set_ifindex(sd_dhcp6_client *client, int ifindex) { + assert_return(client, -EINVAL); + assert_return(ifindex >= -1, -EINVAL); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); - client->index = interface_index; - + client->ifindex = ifindex; return 0; } @@ -671,7 +670,7 @@ static int client_ensure_iaid(sd_dhcp6_client *client) { if (client->ia_na.id) return 0; - r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->ia_na.id); + r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->ia_na.id); if (r < 0) return r; @@ -1027,7 +1026,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { assert_return(client, -EINVAL); assert_return(client->event, -EINVAL); - assert_return(client->index > 0, -EINVAL); + assert_return(client->ifindex > 0, -EINVAL); assert_return(client->state != state, -EINVAL); client->timeout_resend_expire = @@ -1160,12 +1159,12 @@ int sd_dhcp6_client_is_running(sd_dhcp6_client *client) { } int sd_dhcp6_client_start(sd_dhcp6_client *client) { - int r = 0; enum DHCP6State state = DHCP6_STATE_SOLICITATION; + int r = 0; assert_return(client, -EINVAL); assert_return(client->event, -EINVAL); - assert_return(client->index > 0, -EINVAL); + assert_return(client->ifindex > 0, -EINVAL); assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) &client->local_address) > 0, -EINVAL); if (!IN_SET(client->state, DHCP6_STATE_STOPPED)) @@ -1183,7 +1182,7 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { if (r < 0) return r; - r = dhcp6_network_bind_udp_socket(client->index, &client->local_address); + r = dhcp6_network_bind_udp_socket(client->ifindex, &client->local_address); if (r < 0) { _cleanup_free_ char *p = NULL; @@ -1301,15 +1300,11 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) { return -ENOMEM; client->n_ref = 1; - client->ia_na.type = SD_DHCP6_OPTION_IA_NA; - - client->index = -1; - + client->ifindex = -1; client->fd = -1; client->req_opts_len = ELEMENTSOF(default_req_opts); - client->req_opts = new0(be16_t, client->req_opts_len); if (!client->req_opts) return -ENOMEM; diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 3c9fa85198..fcce97cfd9 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -81,7 +81,7 @@ struct sd_ipv4acd { RefCount n_ref; IPv4ACDState state; - int index; + int ifindex; int fd; int iteration; int conflict; @@ -131,7 +131,7 @@ int sd_ipv4acd_new(sd_ipv4acd **ret) { ll->n_ref = REFCNT_INIT; ll->state = IPV4ACD_STATE_INIT; - ll->index = -1; + ll->ifindex = -1; ll->fd = -1; *ret = ll; @@ -264,7 +264,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) case IPV4ACD_STATE_WAITING_PROBE: case IPV4ACD_STATE_PROBING: /* Send a probe */ - r = arp_send_probe(ll->fd, ll->index, ll->address, &ll->mac_addr); + r = arp_send_probe(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { log_ipv4acd_error_errno(ll, r, "Failed to send ARP probe: %m"); goto out; @@ -301,7 +301,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) } case IPV4ACD_STATE_WAITING_ANNOUNCE: /* Send announcement packet */ - r = arp_send_announcement(ll->fd, ll->index, ll->address, &ll->mac_addr); + r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { log_ipv4acd_error_errno(ll, r, "Failed to send ARP announcement: %m"); goto out; @@ -390,7 +390,7 @@ static int ipv4acd_on_packet( /* Defend address */ if (ts > ll->defend_window) { ll->defend_window = ts + DEFEND_INTERVAL * USEC_PER_SEC; - r = arp_send_announcement(ll->fd, ll->index, ll->address, &ll->mac_addr); + r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { log_ipv4acd_error_errno(ll, r, "Failed to send ARP announcement: %m"); goto out; @@ -420,12 +420,12 @@ out: return 1; } -int sd_ipv4acd_set_index(sd_ipv4acd *ll, int interface_index) { +int sd_ipv4acd_set_ifindex(sd_ipv4acd *ll, int ifindex) { assert_return(ll, -EINVAL); - assert_return(interface_index > 0, -EINVAL); + assert_return(ifindex > 0, -EINVAL); assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); - ll->index = interface_index; + ll->ifindex = ifindex; return 0; } @@ -497,14 +497,14 @@ int sd_ipv4acd_start(sd_ipv4acd *ll) { assert_return(ll, -EINVAL); assert_return(ll->event, -EINVAL); - assert_return(ll->index > 0, -EINVAL); + assert_return(ll->ifindex > 0, -EINVAL); assert_return(ll->address != 0, -EINVAL); assert_return(!ether_addr_is_null(&ll->mac_addr), -EINVAL); assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); ll->defend_window = 0; - r = arp_network_bind_raw_socket(ll->index, ll->address, &ll->mac_addr); + r = arp_network_bind_raw_socket(ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) goto out; diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index 2a06418c53..184603de52 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -125,10 +125,11 @@ int sd_ipv4ll_stop(sd_ipv4ll *ll) { return 0; } -int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index) { +int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int ifindex) { assert_return(ll, -EINVAL); + assert_return(ifindex > 0, -EINVAL); - return sd_ipv4acd_set_index(ll->acd, interface_index); + return sd_ipv4acd_set_ifindex(ll->acd, ifindex); } #define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2) diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index bb62cc21a3..ab2527b915 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -75,7 +75,7 @@ struct sd_ndisc { enum NDiscState state; sd_event *event; int event_priority; - int index; + int ifindex; struct ether_addr mac_addr; uint32_t mtu; LIST_HEAD(NDiscPrefix, prefixes); @@ -145,12 +145,11 @@ int sd_ndisc_set_callback(sd_ndisc *nd, return 0; } -int sd_ndisc_set_index(sd_ndisc *nd, int interface_index) { - assert(nd); - assert(interface_index >= -1); - - nd->index = interface_index; +int sd_ndisc_set_ifindex(sd_ndisc *nd, int ifindex) { + assert_return(nd, -EINVAL); + assert_return(ifindex > 0, -EINVAL); + nd->ifindex = ifindex; return 0; } @@ -254,7 +253,7 @@ int sd_ndisc_new(sd_ndisc **ret) { nd->n_ref = 1; - nd->index = -1; + nd->ifindex = -1; nd->fd = -1; LIST_HEAD_INIT(nd->prefixes); @@ -675,10 +674,10 @@ int sd_ndisc_router_discovery_start(sd_ndisc *nd) { if (nd->state != NDISC_STATE_IDLE) return -EBUSY; - if (nd->index < 1) + if (nd->ifindex < 1) return -EINVAL; - r = icmp6_bind_router_solicitation(nd->index); + r = icmp6_bind_router_solicitation(nd->ifindex); if (r < 0) return r; diff --git a/src/libsystemd-network/test-acd.c b/src/libsystemd-network/test-acd.c index 75564615b9..27fcc332a3 100644 --- a/src/libsystemd-network/test-acd.c +++ b/src/libsystemd-network/test-acd.c @@ -56,7 +56,7 @@ static int client_run(int ifindex, const struct in_addr *pa, const struct ether_ assert_se(sd_ipv4acd_new(&acd) >= 0); assert_se(sd_ipv4acd_attach_event(acd, e, 0) >= 0); - assert_se(sd_ipv4acd_set_index(acd, ifindex) >= 0); + assert_se(sd_ipv4acd_set_ifindex(acd, ifindex) >= 0); assert_se(sd_ipv4acd_set_mac(acd, ha) >= 0); assert_se(sd_ipv4acd_set_address(acd, pa) >= 0); assert_se(sd_ipv4acd_set_callback(acd, acd_handler, NULL) >= 0); diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index c3c08fef5e..2a101cb1fe 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -66,13 +66,13 @@ static void test_request_basic(sd_event *e) { assert_se(sd_dhcp_client_set_request_option(NULL, 0) == -EINVAL); assert_se(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL); - assert_se(sd_dhcp_client_set_index(NULL, 0) == -EINVAL); + assert_se(sd_dhcp_client_set_ifindex(NULL, 0) == -EINVAL); - assert_se(sd_dhcp_client_set_index(client, 15) == 0); - assert_se(sd_dhcp_client_set_index(client, -42) == -EINVAL); - assert_se(sd_dhcp_client_set_index(client, -1) == -EINVAL); - assert_se(sd_dhcp_client_set_index(client, 0) == -EINVAL); - assert_se(sd_dhcp_client_set_index(client, 1) == 0); + assert_se(sd_dhcp_client_set_ifindex(client, 15) == 0); + assert_se(sd_dhcp_client_set_ifindex(client, -42) == -EINVAL); + assert_se(sd_dhcp_client_set_ifindex(client, -1) == -EINVAL); + assert_se(sd_dhcp_client_set_ifindex(client, 0) == -EINVAL); + assert_se(sd_dhcp_client_set_ifindex(client, 1) == 0); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_SUBNET_MASK) == -EEXIST); @@ -243,7 +243,7 @@ static void test_discover_message(sd_event *e) { r = sd_dhcp_client_attach_event(client, e, 0); assert_se(r >= 0); - assert_se(sd_dhcp_client_set_index(client, 42) >= 0); + assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0); assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0); assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0); @@ -458,7 +458,7 @@ static void test_addr_acq(sd_event *e) { r = sd_dhcp_client_attach_event(client, e, 0); assert_se(r >= 0); - assert_se(sd_dhcp_client_set_index(client, 42) >= 0); + assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0); assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0); assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e) >= 0); diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index e74c8c72db..bd289fa802 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -59,10 +59,10 @@ static int test_client_basic(sd_event *e) { assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0); - assert_se(sd_dhcp6_client_set_index(client, 15) == 0); - assert_se(sd_dhcp6_client_set_index(client, -42) == -EINVAL); - assert_se(sd_dhcp6_client_set_index(client, -1) == 0); - assert_se(sd_dhcp6_client_set_index(client, 42) >= 0); + assert_se(sd_dhcp6_client_set_ifindex(client, 15) == 0); + assert_se(sd_dhcp6_client_set_ifindex(client, -42) == -EINVAL); + assert_se(sd_dhcp6_client_set_ifindex(client, -1) == 0); + assert_se(sd_dhcp6_client_set_ifindex(client, 42) >= 0); assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr, sizeof (mac_addr), @@ -712,7 +712,7 @@ static int test_client_solicit(sd_event *e) { assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0); - assert_se(sd_dhcp6_client_set_index(client, test_index) == 0); + assert_se(sd_dhcp6_client_set_ifindex(client, test_index) == 0); assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr, sizeof (mac_addr), ARPHRD_ETHER) >= 0); diff --git a/src/libsystemd-network/test-ipv4ll-manual.c b/src/libsystemd-network/test-ipv4ll-manual.c index 85dd61470d..2b1387fa91 100644 --- a/src/libsystemd-network/test-ipv4ll-manual.c +++ b/src/libsystemd-network/test-ipv4ll-manual.c @@ -64,7 +64,7 @@ static int client_run(int ifindex, const char *seed_str, const struct ether_addr assert_se(sd_ipv4ll_new(&ll) >= 0); assert_se(sd_ipv4ll_attach_event(ll, e, 0) >= 0); - assert_se(sd_ipv4ll_set_index(ll, ifindex) >= 0); + assert_se(sd_ipv4ll_set_ifindex(ll, ifindex) >= 0); assert_se(sd_ipv4ll_set_mac(ll, ha) >= 0); assert_se(sd_ipv4ll_set_callback(ll, ll_handler, NULL) >= 0); diff --git a/src/libsystemd-network/test-ipv4ll.c b/src/libsystemd-network/test-ipv4ll.c index 8cdbfb8ed8..aad3c476a0 100644 --- a/src/libsystemd-network/test-ipv4ll.c +++ b/src/libsystemd-network/test-ipv4ll.c @@ -136,11 +136,11 @@ static void test_public_api_setters(sd_event *e) { assert_se(sd_ipv4ll_set_mac(ll, NULL) == -EINVAL); assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0); - assert_se(sd_ipv4ll_set_index(NULL, -1) == -EINVAL); - assert_se(sd_ipv4ll_set_index(ll, -1) == -EINVAL); - assert_se(sd_ipv4ll_set_index(ll, -99) == -EINVAL); - assert_se(sd_ipv4ll_set_index(ll, 1) == 0); - assert_se(sd_ipv4ll_set_index(ll, 99) == 0); + assert_se(sd_ipv4ll_set_ifindex(NULL, -1) == -EINVAL); + assert_se(sd_ipv4ll_set_ifindex(ll, -1) == -EINVAL); + assert_se(sd_ipv4ll_set_ifindex(ll, -99) == -EINVAL); + assert_se(sd_ipv4ll_set_ifindex(ll, 1) == 0); + assert_se(sd_ipv4ll_set_ifindex(ll, 99) == 0); assert_se(sd_ipv4ll_ref(ll) == ll); assert_se(sd_ipv4ll_unref(ll) == NULL); @@ -172,7 +172,7 @@ static void test_basic_request(sd_event *e) { basic_request_handler_userdata) == 0); assert_se(sd_ipv4ll_start(ll) == -EINVAL); - assert_se(sd_ipv4ll_set_index(ll, 1) == 0); + assert_se(sd_ipv4ll_set_ifindex(ll, 1) == 0); assert_se(sd_ipv4ll_start(ll) == 0); sd_event_run(e, (uint64_t) -1); diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c index f7b2eb8050..4817c968ac 100644 --- a/src/libsystemd-network/test-ndisc-rs.c +++ b/src/libsystemd-network/test-ndisc-rs.c @@ -130,7 +130,7 @@ static void test_rs(void) { assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0); - assert_se(sd_ndisc_set_index(nd, 42) >= 0); + assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0); assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0); assert_se(sd_ndisc_set_callback(nd, test_rs_done, NULL, NULL, NULL, e) >= 0); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 2ddcee9db8..12fb8e3fce 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -554,7 +554,7 @@ int dhcp4_configure(Link *link) { if (r < 0) return r; - r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex); + r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex); if (r < 0) return r; diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 37e13e639e..a44c9ea71d 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -237,7 +237,7 @@ int dhcp6_configure(Link *link) { if (r < 0) goto error; - r = sd_dhcp6_client_set_index(client, link->ifindex); + r = sd_dhcp6_client_set_ifindex(client, link->ifindex); if (r < 0) goto error; diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index ae323d595b..a41f231f8c 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -231,7 +231,7 @@ int ipv4ll_configure(Link *link) { if (r < 0) return r; - r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex); + r = sd_ipv4ll_set_ifindex(link->ipv4ll, link->ifindex); if (r < 0) return r; diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 1a380bd214..3baca2e63c 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -243,7 +243,7 @@ int ndisc_configure(Link *link) { if (r < 0) return r; - r = sd_ndisc_set_index(link->ndisc_router_discovery, link->ifindex); + r = sd_ndisc_set_ifindex(link->ndisc_router_discovery, link->ifindex); if (r < 0) return r; diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 20b8c2873f..9a90c2ed42 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -99,7 +99,7 @@ int sd_dhcp_client_set_request_address( int sd_dhcp_client_set_request_broadcast( sd_dhcp_client *client, int broadcast); -int sd_dhcp_client_set_index( +int sd_dhcp_client_set_ifindex( sd_dhcp_client *client, int interface_index); int sd_dhcp_client_set_mac( diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h index 90f62eaca4..7819f0d2de 100644 --- a/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/sd-dhcp6-client.h @@ -82,7 +82,7 @@ int sd_dhcp6_client_set_callback( sd_dhcp6_client_callback_t cb, void *userdata); -int sd_dhcp6_client_set_index( +int sd_dhcp6_client_set_ifindex( sd_dhcp6_client *client, int interface_index); int sd_dhcp6_client_set_local_address( diff --git a/src/systemd/sd-ipv4acd.h b/src/systemd/sd-ipv4acd.h index 9e3e14a30c..604160ae3f 100644 --- a/src/systemd/sd-ipv4acd.h +++ b/src/systemd/sd-ipv4acd.h @@ -44,7 +44,7 @@ int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority); int sd_ipv4acd_get_address(sd_ipv4acd *ll, struct in_addr *address); int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata); int sd_ipv4acd_set_mac(sd_ipv4acd *ll, const struct ether_addr *addr); -int sd_ipv4acd_set_index(sd_ipv4acd *ll, int interface_index); +int sd_ipv4acd_set_ifindex(sd_ipv4acd *ll, int interface_index); int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address); int sd_ipv4acd_is_running(sd_ipv4acd *ll); int sd_ipv4acd_start(sd_ipv4acd *ll); diff --git a/src/systemd/sd-ipv4ll.h b/src/systemd/sd-ipv4ll.h index 6fa38a2243..95ed972ffe 100644 --- a/src/systemd/sd-ipv4ll.h +++ b/src/systemd/sd-ipv4ll.h @@ -43,7 +43,7 @@ int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int64_t priority); int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address); int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdata); int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr); -int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index); +int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int interface_index); int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address); int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, unsigned seed); int sd_ipv4ll_is_running(sd_ipv4ll *ll); diff --git a/src/systemd/sd-ndisc.h b/src/systemd/sd-ndisc.h index 29bcbe8e3e..2b774233b8 100644 --- a/src/systemd/sd-ndisc.h +++ b/src/systemd/sd-ndisc.h @@ -49,7 +49,7 @@ int sd_ndisc_set_callback(sd_ndisc *nd, sd_ndisc_prefix_autonomous_callback_t pacb, sd_ndisc_callback_t cb, void *userdata); -int sd_ndisc_set_index(sd_ndisc *nd, int interface_index); +int sd_ndisc_set_ifindex(sd_ndisc *nd, int interface_index); int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr); int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int64_t priority); -- cgit v1.2.3-54-g00ecf From 5c4c338adc88d6c3c09263a07aa35ff45de85321 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 16:15:04 +0200 Subject: sd-ndisc: rename sd_ndisc_init() to sd_ndisc_reset() After all, it's actually used for resetting the state, not only for the initial initialization. While we are at it, also simplify the error path for sd_ndisc_discovery_start(). --- src/libsystemd-network/sd-ndisc.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index ab2527b915..fe9ba43167 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -209,7 +209,7 @@ sd_ndisc *sd_ndisc_ref(sd_ndisc *nd) { return nd; } -static int ndisc_init(sd_ndisc *nd) { +static int ndisc_reset(sd_ndisc *nd) { assert(nd); nd->recv = sd_event_source_unref(nd->recv); @@ -231,7 +231,7 @@ sd_ndisc *sd_ndisc_unref(sd_ndisc *nd) { if (nd->n_ref > 0) return NULL; - ndisc_init(nd); + ndisc_reset(nd); sd_ndisc_detach_event(nd); LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) @@ -655,7 +655,7 @@ int sd_ndisc_stop(sd_ndisc *nd) { log_ndisc(client, "Stop NDisc"); - ndisc_init(nd); + ndisc_reset(nd); nd->state = NDISC_STATE_IDLE; @@ -683,34 +683,30 @@ int sd_ndisc_router_discovery_start(sd_ndisc *nd) { nd->fd = r; - r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN, - ndisc_router_advertisment_recv, nd); + r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN, ndisc_router_advertisment_recv, nd); if (r < 0) - goto error; + goto fail; r = sd_event_source_set_priority(nd->recv, nd->event_priority); if (r < 0) - goto error; + goto fail; - r = sd_event_source_set_description(nd->recv, "ndisc-receive-message"); - if (r < 0) - goto error; + (void) sd_event_source_set_description(nd->recv, "ndisc-receive-message"); - r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), - 0, 0, ndisc_router_solicitation_timeout, nd); + r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), 0, 0, ndisc_router_solicitation_timeout, nd); if (r < 0) - goto error; + goto fail; r = sd_event_source_set_priority(nd->timeout, nd->event_priority); if (r < 0) - goto error; + goto fail; - r = sd_event_source_set_description(nd->timeout, "ndisc-timeout"); -error: - if (r < 0) - ndisc_init(nd); - else - log_ndisc(client, "Start Router Solicitation"); + (void) sd_event_source_set_description(nd->timeout, "ndisc-timeout"); + + log_ndisc(client, "Started IPv6 Router Solicitation client"); + return 0; +fail: + ndisc_reset(nd); return r; } -- cgit v1.2.3-54-g00ecf From a114066685b6a996c3f0ae914ee32587e8f59f2f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 16:27:05 +0200 Subject: sd-network: fix up assertion chaos assert_return() should only be used to validate user-facing parameters and state, assert() should be used for checking our own internal state and parameters. --- src/libsystemd-network/sd-dhcp-client.c | 41 +++++++++++++++++------------ src/libsystemd-network/sd-dhcp6-client.c | 35 +++++++++++++++++-------- src/libsystemd-network/sd-ndisc.c | 44 +++++++++++++++----------------- 3 files changed, 68 insertions(+), 52 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index fab9f3f088..09e174cc01 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -151,10 +151,10 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) { size_t i; assert_return(client, -EINVAL); - assert_return (IN_SET(client->state, DHCP_STATE_INIT, - DHCP_STATE_STOPPED), -EBUSY); + assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY); switch(option) { + case SD_DHCP_OPTION_PAD: case SD_DHCP_OPTION_OVERLOAD: case SD_DHCP_OPTION_MESSAGE_TYPE: @@ -182,9 +182,9 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) { int sd_dhcp_client_set_request_address( sd_dhcp_client *client, const struct in_addr *last_addr) { + assert_return(client, -EINVAL); - assert_return (IN_SET(client->state, DHCP_STATE_INIT, - DHCP_STATE_STOPPED), -EBUSY); + assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY); if (last_addr) client->last_addr = last_addr->s_addr; @@ -230,8 +230,7 @@ int sd_dhcp_client_set_mac( return 0; if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) { - log_dhcp_client(client, "Changing MAC address on running DHCP " - "client, restarting"); + log_dhcp_client(client, "Changing MAC address on running DHCP client, restarting"); need_restart = true; client_stop(client, SD_DHCP_CLIENT_EVENT_STOP); } @@ -283,14 +282,17 @@ int sd_dhcp_client_set_client_id( assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL); switch (type) { + case ARPHRD_ETHER: if (data_len != ETH_ALEN) return -EINVAL; break; + case ARPHRD_INFINIBAND: if (data_len != INFINIBAND_ALEN) return -EINVAL; break; + default: break; } @@ -434,14 +436,14 @@ int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) { int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) { assert_return(client, -EINVAL); - assert_return(ret, -EINVAL); if (client->state != DHCP_STATE_BOUND && client->state != DHCP_STATE_RENEWING && client->state != DHCP_STATE_REBINDING) return -EADDRNOTAVAIL; - *ret = client->lease; + if (ret) + *ret = client->lease; return 0; } @@ -454,8 +456,7 @@ static void client_notify(sd_dhcp_client *client, int event) { static int client_initialize(sd_dhcp_client *client) { assert_return(client, -EINVAL); - client->receive_message = - sd_event_source_unref(client->receive_message); + client->receive_message = sd_event_source_unref(client->receive_message); client->fd = asynchronous_close(client->fd); @@ -750,8 +751,9 @@ static int client_send_request(sd_dhcp_client *client) { size_t optoffset, optlen; int r; - r = client_message_init(client, &request, DHCP_REQUEST, - &optlen, &optoffset); + assert(client); + + r = client_message_init(client, &request, DHCP_REQUEST, &optlen, &optoffset); if (r < 0) return r; @@ -848,18 +850,23 @@ static int client_send_request(sd_dhcp_client *client) { return r; switch (client->state) { + case DHCP_STATE_REQUESTING: log_dhcp_client(client, "REQUEST (requesting)"); break; + case DHCP_STATE_INIT_REBOOT: log_dhcp_client(client, "REQUEST (init-reboot)"); break; + case DHCP_STATE_RENEWING: log_dhcp_client(client, "REQUEST (renewing)"); break; + case DHCP_STATE_REBINDING: log_dhcp_client(client, "REQUEST (rebinding)"); break; + default: log_dhcp_client(client, "REQUEST (invalid)"); break; @@ -891,6 +898,7 @@ static int client_timeout_resend( goto error; switch (client->state) { + case DHCP_STATE_RENEWING: time_left = (client->lease->t2 - client->lease->t1) / 2; @@ -1103,8 +1111,7 @@ static int client_start_delayed(sd_dhcp_client *client) { assert_return(client->ifindex > 0, -EINVAL); assert_return(client->fd < 0, -EBUSY); assert_return(client->xid == 0, -EINVAL); - assert_return(client->state == DHCP_STATE_INIT || - client->state == DHCP_STATE_INIT_REBOOT, -EBUSY); + assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT), -EBUSY); client->xid = random_u32(); @@ -1150,6 +1157,8 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) DHCP_CLIENT_DONT_DESTROY(client); int r; + assert(client); + client->receive_message = sd_event_source_unref(client->receive_message); client->fd = asynchronous_close(client->fd); @@ -1821,8 +1830,7 @@ int sd_dhcp_client_detach_event(sd_dhcp_client *client) { } sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) { - if (!client) - return NULL; + assert_return(client, NULL); return client->event; } @@ -1884,7 +1892,6 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) { client->mtu = DHCP_DEFAULT_MIN_SIZE; client->req_opts_size = ELEMENTSOF(default_req_opts); - client->req_opts = memdup(default_req_opts, client->req_opts_size); if (!client->req_opts) return -ENOMEM; diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 15667c26d7..203deaa50d 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -255,6 +255,7 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option) assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY); switch(option) { + case SD_DHCP6_OPTION_DNS_SERVERS: case SD_DHCP6_OPTION_DOMAIN_LIST: case SD_DHCP6_OPTION_SNTP_SERVERS: @@ -296,15 +297,18 @@ static void client_notify(sd_dhcp6_client *client, int event) { } static void client_set_lease(sd_dhcp6_client *client, sd_dhcp6_lease *lease) { + assert(client); + if (client->lease) { dhcp6_lease_clear_timers(&client->lease->ia); sd_dhcp6_lease_unref(client->lease); } + client->lease = lease; } static int client_reset(sd_dhcp6_client *client) { - assert_return(client, -EINVAL); + assert(client); client_set_lease(client, NULL); @@ -352,6 +356,8 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { usec_t elapsed_usec; be16_t elapsed_time; + assert(client); + len = sizeof(DHCP6Message) + optlen; message = malloc0(len); @@ -453,9 +459,9 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp6_client *client = userdata; - assert_return(s, -EINVAL); - assert_return(client, -EINVAL); - assert_return(client->lease, -EINVAL); + assert(s); + assert(client); + assert(client->lease); client->lease->ia.timeout_t2 = sd_event_source_unref(client->lease->ia.timeout_t2); @@ -470,9 +476,9 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp6_client *client = userdata; - assert_return(s, -EINVAL); - assert_return(client, -EINVAL); - assert_return(client->lease, -EINVAL); + assert(s); + assert(client); + assert(client->lease); client->lease->ia.timeout_t1 = sd_event_source_unref(client->lease->ia.timeout_t1); @@ -689,6 +695,11 @@ static int client_parse_message( bool clientid = false; be32_t iaid_lease; + assert(client); + assert(message); + assert(len >= sizeof(DHCP6Message)); + assert(lease); + option = (uint8_t *)message + sizeof(DHCP6Message); len -= sizeof(DHCP6Message); @@ -833,9 +844,12 @@ static int client_parse_message( } static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, size_t len) { - int r; _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL; bool rapid_commit; + int r; + + assert(client); + assert(reply); if (reply->type != DHCP6_REPLY) return 0; @@ -864,9 +878,9 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, si } static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *advertise, size_t len) { - int r; _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL; uint8_t pref_advertise = 0, pref_lease = 0; + int r; if (advertise->type != DHCP6_ADVERTISE) return 0; @@ -1251,8 +1265,7 @@ int sd_dhcp6_client_detach_event(sd_dhcp6_client *client) { } sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) { - if (!client) - return NULL; + assert_return(client, NULL); return client->event; } diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index fe9ba43167..06afafd2c7 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -128,13 +128,15 @@ static int ndisc_prefix_new(sd_ndisc *nd, NDiscPrefix **ret) { return 0; } -int sd_ndisc_set_callback(sd_ndisc *nd, - sd_ndisc_router_callback_t router_callback, - sd_ndisc_prefix_onlink_callback_t prefix_onlink_callback, - sd_ndisc_prefix_autonomous_callback_t prefix_autonomous_callback, - sd_ndisc_callback_t callback, - void *userdata) { - assert(nd); +int sd_ndisc_set_callback( + sd_ndisc *nd, + sd_ndisc_router_callback_t router_callback, + sd_ndisc_prefix_onlink_callback_t prefix_onlink_callback, + sd_ndisc_prefix_autonomous_callback_t prefix_autonomous_callback, + sd_ndisc_callback_t callback, + void *userdata) { + + assert_return(nd, -EINVAL); nd->router_callback = router_callback; nd->prefix_onlink_callback = prefix_onlink_callback; @@ -154,7 +156,7 @@ int sd_ndisc_set_ifindex(sd_ndisc *nd, int ifindex) { } int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr) { - assert(nd); + assert_return(nd, -EINVAL); if (mac_addr) memcpy(&nd->mac_addr, mac_addr, sizeof(nd->mac_addr)); @@ -193,7 +195,7 @@ int sd_ndisc_detach_event(sd_ndisc *nd) { } sd_event *sd_ndisc_get_event(sd_ndisc *nd) { - assert(nd); + assert_return(nd, NULL); return nd->event; } @@ -245,14 +247,13 @@ sd_ndisc *sd_ndisc_unref(sd_ndisc *nd) { int sd_ndisc_new(sd_ndisc **ret) { _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL; - assert(ret); + assert_return(ret, -EINVAL); nd = new0(sd_ndisc, 1); if (!nd) return -ENOMEM; nd->n_ref = 1; - nd->ifindex = -1; nd->fd = -1; @@ -272,7 +273,6 @@ int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu) { return -ENOMSG; *mtu = nd->mtu; - return 0; } @@ -281,8 +281,8 @@ static int prefix_match(const struct in6_addr *prefix, uint8_t prefixlen, uint8_t addr_prefixlen) { uint8_t bytes, mask, len; - assert_return(prefix, -EINVAL); - assert_return(addr, -EINVAL); + assert(prefix); + assert(addr); len = MIN(prefixlen, addr_prefixlen); @@ -414,8 +414,8 @@ static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, ssize_t len void *opt; struct nd_opt_hdr *opt_hdr; - assert_return(nd, -EINVAL); - assert_return(ra, -EINVAL); + assert(nd); + assert(ra); len -= sizeof(*ra); if (len < NDISC_OPT_LEN_UNITS) { @@ -668,14 +668,10 @@ int sd_ndisc_stop(sd_ndisc *nd) { int sd_ndisc_router_discovery_start(sd_ndisc *nd) { int r; - assert(nd); - assert(nd->event); - - if (nd->state != NDISC_STATE_IDLE) - return -EBUSY; - - if (nd->ifindex < 1) - return -EINVAL; + assert_return(nd, -EINVAL); + assert_return(nd->event, -EINVAL); + assert_return(nd->ifindex > 0, -EINVAL); + assert_return(nd->state == NDISC_STATE_IDLE, -EBUSY); r = icmp6_bind_router_solicitation(nd->ifindex); if (r < 0) -- cgit v1.2.3-54-g00ecf From c1c9b211e3337e3491acc5f2550e8d48542986aa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 16:27:59 +0200 Subject: sd-ndisc: make the _stop() call idempotent It's a good idea to make stopcalls idempotent, so that they become nops if the object is already stopped. --- src/libsystemd-network/sd-ndisc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 06afafd2c7..c03e104e3b 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -651,12 +651,13 @@ static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, int sd_ndisc_stop(sd_ndisc *nd) { assert_return(nd, -EINVAL); - assert_return(nd->event, -EINVAL); - log_ndisc(client, "Stop NDisc"); + if (nd->state == NDISC_STATE_IDLE) + return 0; + + log_ndisc(client, "Stopping IPv6 Router Solicitation client"); ndisc_reset(nd); - nd->state = NDISC_STATE_IDLE; if (nd->callback) -- cgit v1.2.3-54-g00ecf From 671eaa74050fc2683a068a7e90bb5e66ef038395 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 16:46:50 +0200 Subject: dhcp: fix operator precedence issue with macro --- src/libsystemd-network/dhcp-protocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-protocol.h b/src/libsystemd-network/dhcp-protocol.h index 3e32484c1d..5cf7abbff9 100644 --- a/src/libsystemd-network/dhcp-protocol.h +++ b/src/libsystemd-network/dhcp-protocol.h @@ -59,7 +59,7 @@ typedef struct DHCPPacket DHCPPacket; #define DHCP_IP_UDP_SIZE (int32_t)(sizeof(struct udphdr) + DHCP_IP_SIZE) #define DHCP_MESSAGE_SIZE (int32_t)(sizeof(DHCPMessage)) #define DHCP_DEFAULT_MIN_SIZE 576 /* the minimum internet hosts must be able to receive */ -#define DHCP_MIN_OPTIONS_SIZE DHCP_DEFAULT_MIN_SIZE - DHCP_IP_UDP_SIZE - DHCP_MESSAGE_SIZE +#define DHCP_MIN_OPTIONS_SIZE (DHCP_DEFAULT_MIN_SIZE - DHCP_IP_UDP_SIZE - DHCP_MESSAGE_SIZE) #define DHCP_MAGIC_COOKIE (uint32_t)(0x63825363) enum { -- cgit v1.2.3-54-g00ecf From 45aa74c72e4a315403611ebff5415dc1e8a196ed Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 16:48:56 +0200 Subject: sd-network: don't needlessly abbreviate "callback" as "cb" in struct members It's OK to abbreviate this in the local scope, but otherwise, let's not be needlessly terse. --- src/libsystemd-network/sd-dhcp-client.c | 11 +++++++---- src/libsystemd-network/sd-dhcp6-client.c | 11 +++++++---- src/libsystemd-network/sd-ipv4acd.c | 8 ++++---- src/libsystemd-network/sd-ipv4ll.c | 8 ++++---- 4 files changed, 22 insertions(+), 16 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 09e174cc01..179e5950bd 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -101,7 +101,7 @@ struct sd_dhcp_client { sd_event_source *timeout_t1; sd_event_source *timeout_t2; sd_event_source *timeout_expire; - sd_dhcp_client_callback_t cb; + sd_dhcp_client_callback_t callback; void *userdata; sd_dhcp_lease *lease; usec_t start_delay; @@ -131,9 +131,10 @@ int sd_dhcp_client_set_callback( sd_dhcp_client *client, sd_dhcp_client_callback_t cb, void *userdata) { + assert_return(client, -EINVAL); - client->cb = cb; + client->callback = cb; client->userdata = userdata; return 0; @@ -449,8 +450,10 @@ int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) { } static void client_notify(sd_dhcp_client *client, int event) { - if (client->cb) - client->cb(client, event, client->userdata); + assert(client); + + if (client->callback) + client->callback(client, event, client->userdata); } static int client_initialize(sd_dhcp_client *client) { diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 203deaa50d..463fde401c 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -64,7 +64,7 @@ struct sd_dhcp6_client { uint8_t retransmit_count; sd_event_source *timeout_resend; sd_event_source *timeout_resend_expire; - sd_dhcp6_client_callback_t cb; + sd_dhcp6_client_callback_t callback; void *userdata; struct duid duid; size_t duid_len; @@ -115,9 +115,10 @@ int sd_dhcp6_client_set_callback( sd_dhcp6_client *client, sd_dhcp6_client_callback_t cb, void *userdata) { + assert_return(client, -EINVAL); - client->cb = cb; + client->callback = cb; client->userdata = userdata; return 0; @@ -292,8 +293,10 @@ int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) { } static void client_notify(sd_dhcp6_client *client, int event) { - if (client->cb) - client->cb(client, event, client->userdata); + assert(client); + + if (client->callback) + client->callback(client, event, client->userdata); } static void client_set_lease(sd_dhcp6_client *client, sd_dhcp6_lease *lease) { diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index fcce97cfd9..7414f33adb 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -93,7 +93,7 @@ struct sd_ipv4acd { struct ether_addr mac_addr; sd_event *event; int event_priority; - sd_ipv4acd_callback_t cb; + sd_ipv4acd_callback_t callback; void* userdata; }; @@ -156,10 +156,10 @@ static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counte static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) { assert(ll); - if (!ll->cb) + if (!ll->callback) return; - ll->cb(ll, event, ll->userdata); + ll->callback(ll, event, ll->userdata); } static void ipv4acd_stop(sd_ipv4acd *ll) { @@ -470,7 +470,7 @@ int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority) { int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata) { assert_return(ll, -EINVAL); - ll->cb = cb; + ll->callback = cb; ll->userdata = userdata; return 0; diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index 184603de52..f9779a8601 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -52,7 +52,7 @@ struct sd_ipv4ll { /* External */ be32_t claimed_address; - sd_ipv4ll_callback_t cb; + sd_ipv4ll_callback_t callback; void* userdata; }; @@ -176,7 +176,7 @@ int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int64_t priority) { int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdata) { assert_return(ll, -EINVAL); - ll->cb = cb; + ll->callback = cb; ll->userdata = userdata; return 0; @@ -312,8 +312,8 @@ int sd_ipv4ll_start(sd_ipv4ll *ll) { static void ipv4ll_client_notify(sd_ipv4ll *ll, int event) { assert(ll); - if (ll->cb) - ll->cb(ll, event, ll->userdata); + if (ll->callback) + ll->callback(ll, event, ll->userdata); } void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) { -- cgit v1.2.3-54-g00ecf From c116f52635c96548986b8e6f877ceaafec2a80bf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 17:17:37 +0200 Subject: sd-ipv4{acl,ll}: don't make use of RefCnt objects These objects are only useful when multiple threads are involved, as they operate with atomic operations. Given that our libraries are explicitly not thread-safe don't make use of RefCnt here, and make things a bit simpler. --- src/libsystemd-network/sd-ipv4acd.c | 20 ++++++++++++++------ src/libsystemd-network/sd-ipv4ll.c | 1 - 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 7414f33adb..5f6e0f6c7f 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -33,7 +33,6 @@ #include "in-addr-util.h" #include "list.h" #include "random-util.h" -#include "refcnt.h" #include "siphash24.h" #include "util.h" @@ -78,7 +77,7 @@ typedef enum IPv4ACDState { } IPv4ACDState; struct sd_ipv4acd { - RefCount n_ref; + unsigned n_ref; IPv4ACDState state; int ifindex; @@ -98,14 +97,23 @@ struct sd_ipv4acd { }; sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *ll) { - if (ll) - assert_se(REFCNT_INC(ll->n_ref) >= 2); + if (!ll) + return NULL; + + assert_se(ll->n_ref >= 1); + ll->n_ref++; return ll; } sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *ll) { - if (!ll || REFCNT_DEC(ll->n_ref) > 0) + if (!ll) + return NULL; + + assert_se(ll->n_ref >= 1); + ll->n_ref--; + + if (ll->n_ref > 0) return NULL; ll->receive_message = sd_event_source_unref(ll->receive_message); @@ -129,7 +137,7 @@ int sd_ipv4acd_new(sd_ipv4acd **ret) { if (!ll) return -ENOMEM; - ll->n_ref = REFCNT_INIT; + ll->n_ref = 1; ll->state = IPV4ACD_STATE_INIT; ll->ifindex = -1; ll->fd = -1; diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index f9779a8601..ea6d9d22f1 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -31,7 +31,6 @@ #include "in-addr-util.h" #include "list.h" #include "random-util.h" -#include "refcnt.h" #include "siphash24.h" #include "sparse-endian.h" #include "util.h" -- cgit v1.2.3-54-g00ecf From a48fc60a331803fcd4add17cdb5b3cae99bc2e80 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 17:18:58 +0200 Subject: ipv4acd: library code should never log Or actually, not at any level higher than debug. --- src/libsystemd-network/sd-ipv4acd.c | 38 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 24 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 5f6e0f6c7f..2fc8651399 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -51,19 +51,8 @@ #define IPV4ACD_NETWORK 0xA9FE0000L #define IPV4ACD_NETMASK 0xFFFF0000L -#define log_ipv4acd_full(ll, level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "ACD: " fmt, ##__VA_ARGS__) - -#define log_ipv4acd_debug(ll, ...) log_ipv4acd_full(ll, LOG_DEBUG, 0, ##__VA_ARGS__) -#define log_ipv4acd_info(ll, ...) log_ipv4acd_full(ll, LOG_INFO, 0, ##__VA_ARGS__) -#define log_ipv4acd_notice(ll, ...) log_ipv4acd_full(ll, LOG_NOTICE, 0, ##__VA_ARGS__) -#define log_ipv4acd_warning(ll, ...) log_ipv4acd_full(ll, LOG_WARNING, 0, ##__VA_ARGS__) -#define log_ipv4acd_error(ll, ...) log_ipv4acd_full(ll, LOG_ERR, 0, ##__VA_ARGS__) - -#define log_ipv4acd_debug_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_DEBUG, error, ##__VA_ARGS__) -#define log_ipv4acd_info_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_INFO, error, ##__VA_ARGS__) -#define log_ipv4acd_notice_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_NOTICE, error, ##__VA_ARGS__) -#define log_ipv4acd_warning_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_WARNING, error, ##__VA_ARGS__) -#define log_ipv4acd_error_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_ERR, error, ##__VA_ARGS__) +#define log_ipv4acd_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "ACD: " fmt, ##__VA_ARGS__) +#define log_ipv4acd(ll, fmt, ...) log_ipv4acd_errno(ll, 0, fmt, ##__VA_ARGS__) typedef enum IPv4ACDState { IPV4ACD_STATE_INIT, @@ -178,7 +167,7 @@ static void ipv4acd_stop(sd_ipv4acd *ll) { ll->timer = sd_event_source_unref(ll->timer); - log_ipv4acd_debug(ll, "STOPPED"); + log_ipv4acd(ll, "STOPPED"); ipv4acd_set_state (ll, IPV4ACD_STATE_INIT, true); } @@ -256,7 +245,8 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_PROBE, true); if (ll->conflict >= MAX_CONFLICTS) { - log_ipv4acd_notice(ll, "Max conflicts reached, delaying by %us", RATE_LIMIT_INTERVAL); + log_ipv4acd(ll, "Max conflicts reached, delaying by %us", RATE_LIMIT_INTERVAL); + r = ipv4acd_set_next_wakeup(ll, RATE_LIMIT_INTERVAL, PROBE_WAIT); if (r < 0) goto out; @@ -274,7 +264,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) /* Send a probe */ r = arp_send_probe(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { - log_ipv4acd_error_errno(ll, r, "Failed to send ARP probe: %m"); + log_ipv4acd_errno(ll, r, "Failed to send ARP probe: %m"); goto out; } else { _cleanup_free_ char *address = NULL; @@ -282,7 +272,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) r = in_addr_to_string(AF_INET, &addr, &address); if (r >= 0) - log_ipv4acd_debug(ll, "Probing %s", address); + log_ipv4acd(ll, "Probing %s", address); } if (ll->iteration < PROBE_NUM - 2) { @@ -311,10 +301,10 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) /* Send announcement packet */ r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { - log_ipv4acd_error_errno(ll, r, "Failed to send ARP announcement: %m"); + log_ipv4acd_errno(ll, r, "Failed to send ARP announcement: %m"); goto out; } else - log_ipv4acd_debug(ll, "ANNOUNCE"); + log_ipv4acd(ll, "ANNOUNCE"); ipv4acd_set_state(ll, IPV4ACD_STATE_ANNOUNCING, false); @@ -350,7 +340,7 @@ static void ipv4acd_on_conflict(sd_ipv4acd *ll) { r = in_addr_to_string(AF_INET, &addr, &address); if (r >= 0) - log_ipv4acd_debug(ll, "Conflict on %s (%u)", address, ll->conflict); + log_ipv4acd(ll, "Conflict on %s (%u)", address, ll->conflict); ipv4acd_stop(ll); @@ -377,11 +367,11 @@ static int ipv4acd_on_packet( if (errno == EAGAIN || errno == EINTR) return 0; - r = log_ipv4acd_debug_errno(ll, errno, "Failed to read ARP packet: %m"); + r = log_ipv4acd_errno(ll, errno, "Failed to read ARP packet: %m"); goto out; } if ((size_t) n != sizeof(struct ether_arp)) { - log_ipv4acd_debug(ll, "Ignoring too short ARP packet."); + log_ipv4acd(ll, "Ignoring too short ARP packet."); return 0; } @@ -400,10 +390,10 @@ static int ipv4acd_on_packet( ll->defend_window = ts + DEFEND_INTERVAL * USEC_PER_SEC; r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { - log_ipv4acd_error_errno(ll, r, "Failed to send ARP announcement: %m"); + log_ipv4acd_errno(ll, r, "Failed to send ARP announcement: %m"); goto out; } else - log_ipv4acd_debug(ll, "DEFEND"); + log_ipv4acd(ll, "DEFEND"); } else ipv4acd_on_conflict(ll); -- cgit v1.2.3-54-g00ecf From 73e94c0dcb41c0924d506a329f874e69409437f6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 17:19:35 +0200 Subject: ipv4l-{acd,ll}: make sure ipv4 addresses are unsigned And some other minor fixes. --- src/libsystemd-network/sd-ipv4acd.c | 4 ++-- src/libsystemd-network/sd-ipv4ll.c | 20 +++++++------------- src/systemd/sd-ipv4ll.h | 2 +- 3 files changed, 10 insertions(+), 16 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 2fc8651399..e78d8a04f2 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -48,8 +48,8 @@ #define RATE_LIMIT_INTERVAL 60 #define DEFEND_INTERVAL 10 -#define IPV4ACD_NETWORK 0xA9FE0000L -#define IPV4ACD_NETMASK 0xFFFF0000L +#define IPV4ACD_NETWORK 0xA9FE0000UL +#define IPV4ACD_NETMASK 0xFFFF0000UL #define log_ipv4acd_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "ACD: " fmt, ##__VA_ARGS__) #define log_ipv4acd(ll, fmt, ...) log_ipv4acd_errno(ll, 0, fmt, ##__VA_ARGS__) diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index ea6d9d22f1..1f6da4bb16 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -35,8 +35,8 @@ #include "sparse-endian.h" #include "util.h" -#define IPV4LL_NETWORK 0xA9FE0000L -#define IPV4LL_NETMASK 0xFFFF0000L +#define IPV4LL_NETWORK 0xA9FE0000UL +#define IPV4LL_NETMASK 0xFFFF0000UL #define IPV4LL_DONT_DESTROY(ll) \ _cleanup_(sd_ipv4ll_unrefp) _unused_ sd_ipv4ll *_dont_destroy_##ll = sd_ipv4ll_ref(ll) @@ -161,15 +161,9 @@ int sd_ipv4ll_detach_event(sd_ipv4ll *ll) { } int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int64_t priority) { - int r; - assert_return(ll, -EINVAL); - r = sd_ipv4acd_attach_event(ll->acd, event, priority); - if (r < 0) - return r; - - return 0; + return sd_ipv4acd_attach_event(ll->acd, event, priority); } int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdata) { @@ -275,7 +269,7 @@ static int ipv4ll_pick_address(sd_ipv4ll *ll) { r = random_r(ll->random_data, &random); if (r < 0) return r; - addr = htonl((random & 0x0000FFFF) | IPV4LL_NETWORK); + addr = htobe32((random & 0x0000FFFF) | IPV4LL_NETWORK); } while (addr == ll->address || (ntohl(addr) & 0x0000FF00) == 0x0000 || (ntohl(addr) & 0x0000FF00) == 0xFF00); @@ -324,17 +318,17 @@ void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) { assert(ll); switch (event) { + case SD_IPV4ACD_EVENT_STOP: ipv4ll_client_notify(ll, SD_IPV4LL_EVENT_STOP); - ll->claimed_address = 0; - break; + case SD_IPV4ACD_EVENT_BIND: ll->claimed_address = ll->address; ipv4ll_client_notify(ll, SD_IPV4LL_EVENT_BIND); - break; + case SD_IPV4ACD_EVENT_CONFLICT: /* if an address was already bound we must call up to the user to handle this, otherwise we just try again */ diff --git a/src/systemd/sd-ipv4ll.h b/src/systemd/sd-ipv4ll.h index 95ed972ffe..4682dd6605 100644 --- a/src/systemd/sd-ipv4ll.h +++ b/src/systemd/sd-ipv4ll.h @@ -51,7 +51,7 @@ int sd_ipv4ll_start(sd_ipv4ll *ll); int sd_ipv4ll_stop(sd_ipv4ll *ll); sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll); sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll); -int sd_ipv4ll_new (sd_ipv4ll **ret); +int sd_ipv4ll_new(sd_ipv4ll **ret); _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ipv4ll, sd_ipv4ll_unref); -- cgit v1.2.3-54-g00ecf From 784cdc2d0bb1e4102345fc3883e1e4587f0ec967 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 17:23:40 +0200 Subject: ipv4acd: make the iteration and conflict fields unsigned They are counters after all, and can never go below zero, hence don't pretend with the chose type that they could. Also, prefix their name with "n_", to indicate that they are counters. --- src/libsystemd-network/sd-ipv4acd.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index e78d8a04f2..730b8ca785 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -71,14 +71,19 @@ struct sd_ipv4acd { IPv4ACDState state; int ifindex; int fd; - int iteration; - int conflict; + + unsigned n_iteration; + unsigned n_conflict; + sd_event_source *receive_message; sd_event_source *timer; + usec_t defend_window; be32_t address; + /* External */ struct ether_addr mac_addr; + sd_event *event; int event_priority; sd_ipv4acd_callback_t callback; @@ -143,10 +148,10 @@ static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counte assert(st < _IPV4ACD_STATE_MAX); if (st == ll->state && !reset_counter) - ll->iteration++; + ll->n_iteration++; else { ll->state = st; - ll->iteration = 0; + ll->n_iteration = 0; } } @@ -244,14 +249,14 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_PROBE, true); - if (ll->conflict >= MAX_CONFLICTS) { + if (ll->n_conflict >= MAX_CONFLICTS) { log_ipv4acd(ll, "Max conflicts reached, delaying by %us", RATE_LIMIT_INTERVAL); r = ipv4acd_set_next_wakeup(ll, RATE_LIMIT_INTERVAL, PROBE_WAIT); if (r < 0) goto out; - ll->conflict = 0; + ll->n_conflict = 0; } else { r = ipv4acd_set_next_wakeup(ll, 0, PROBE_WAIT); if (r < 0) @@ -275,7 +280,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) log_ipv4acd(ll, "Probing %s", address); } - if (ll->iteration < PROBE_NUM - 2) { + if (ll->n_iteration < PROBE_NUM - 2) { ipv4acd_set_state(ll, IPV4ACD_STATE_PROBING, false); r = ipv4acd_set_next_wakeup(ll, PROBE_MIN, (PROBE_MAX-PROBE_MIN)); @@ -292,7 +297,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) break; case IPV4ACD_STATE_ANNOUNCING: - if (ll->iteration >= ANNOUNCE_NUM - 1) { + if (ll->n_iteration >= ANNOUNCE_NUM - 1) { ipv4acd_set_state(ll, IPV4ACD_STATE_RUNNING, false); break; @@ -312,8 +317,8 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) if (r < 0) goto out; - if (ll->iteration == 0) { - ll->conflict = 0; + if (ll->n_iteration == 0) { + ll->n_conflict = 0; ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_BIND); } @@ -336,11 +341,11 @@ static void ipv4acd_on_conflict(sd_ipv4acd *ll) { assert(ll); - ll->conflict++; + ll->n_conflict++; r = in_addr_to_string(AF_INET, &addr, &address); if (r >= 0) - log_ipv4acd(ll, "Conflict on %s (%u)", address, ll->conflict); + log_ipv4acd(ll, "Conflict on %s (%u)", address, ll->n_conflict); ipv4acd_stop(ll); -- cgit v1.2.3-54-g00ecf From 4dbf7b3a9330482b21685e57d3098a67693e2956 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 17:32:18 +0200 Subject: ipv4acd: add "_event_source" suffix to event source objects Otherwise the field "receive_message" is a bit too confusing, as it suggests it actually stores a message object of some kind. --- src/libsystemd-network/sd-ipv4acd.c | 45 +++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 24 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 730b8ca785..7393be45f5 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -75,8 +75,8 @@ struct sd_ipv4acd { unsigned n_iteration; unsigned n_conflict; - sd_event_source *receive_message; - sd_event_source *timer; + sd_event_source *receive_message_event_source; + sd_event_source *timer_event_source; usec_t defend_window; be32_t address; @@ -110,10 +110,10 @@ sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *ll) { if (ll->n_ref > 0) return NULL; - ll->receive_message = sd_event_source_unref(ll->receive_message); - ll->fd = safe_close(ll->fd); + ll->timer_event_source = sd_event_source_unref(ll->timer_event_source); + ll->receive_message_event_source = sd_event_source_unref(ll->receive_message_event_source); - ll->timer = sd_event_source_unref(ll->timer); + ll->fd = safe_close(ll->fd); sd_ipv4acd_detach_event(ll); @@ -143,7 +143,6 @@ int sd_ipv4acd_new(sd_ipv4acd **ret) { } static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counter) { - assert(ll); assert(st < _IPV4ACD_STATE_MAX); @@ -167,21 +166,20 @@ static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) { static void ipv4acd_stop(sd_ipv4acd *ll) { assert(ll); - ll->receive_message = sd_event_source_unref(ll->receive_message); - ll->fd = safe_close(ll->fd); + ll->timer_event_source = sd_event_source_unref(ll->timer_event_source); - ll->timer = sd_event_source_unref(ll->timer); + ll->receive_message_event_source = sd_event_source_unref(ll->receive_message_event_source); + ll->fd = safe_close(ll->fd); log_ipv4acd(ll, "STOPPED"); - ipv4acd_set_state (ll, IPV4ACD_STATE_INIT, true); + ipv4acd_set_state(ll, IPV4ACD_STATE_INIT, true); } int sd_ipv4acd_stop(sd_ipv4acd *ll) { assert_return(ll, -EINVAL); ipv4acd_stop(ll); - ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_STOP); return 0; @@ -215,12 +213,10 @@ static int ipv4acd_set_next_wakeup(sd_ipv4acd *ll, int sec, int random_sec) { if (r < 0) return r; - r = sd_event_source_set_description(timer, "ipv4acd-timer"); - if (r < 0) - return r; + (void) sd_event_source_set_description(timer, "ipv4acd-timer"); - ll->timer = sd_event_source_unref(ll->timer); - ll->timer = timer; + sd_event_source_unref(ll->timer_event_source); + ll->timer_event_source = timer; timer = NULL; return 0; @@ -245,8 +241,8 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) assert(ll); switch (ll->state) { - case IPV4ACD_STATE_INIT: + case IPV4ACD_STATE_INIT: ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_PROBE, true); if (ll->n_conflict >= MAX_CONFLICTS) { @@ -264,6 +260,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) } break; + case IPV4ACD_STATE_WAITING_PROBE: case IPV4ACD_STATE_PROBING: /* Send a probe */ @@ -299,9 +296,11 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) case IPV4ACD_STATE_ANNOUNCING: if (ll->n_iteration >= ANNOUNCE_NUM - 1) { ipv4acd_set_state(ll, IPV4ACD_STATE_RUNNING, false); - break; } + + /* fall through */ + case IPV4ACD_STATE_WAITING_ANNOUNCE: /* Send announcement packet */ r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); @@ -323,6 +322,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) } break; + default: assert_not_reached("Invalid state."); } @@ -514,18 +514,15 @@ int sd_ipv4acd_start(sd_ipv4acd *ll) { ll->fd = safe_close(ll->fd); ll->fd = r; - r = sd_event_add_io(ll->event, &ll->receive_message, ll->fd, - EPOLLIN, ipv4acd_on_packet, ll); + r = sd_event_add_io(ll->event, &ll->receive_message_event_source, ll->fd, EPOLLIN, ipv4acd_on_packet, ll); if (r < 0) goto out; - r = sd_event_source_set_priority(ll->receive_message, ll->event_priority); + r = sd_event_source_set_priority(ll->receive_message_event_source, ll->event_priority); if (r < 0) goto out; - r = sd_event_source_set_description(ll->receive_message, "ipv4acd-receive-message"); - if (r < 0) - goto out; + (void) sd_event_source_set_description(ll->receive_message_event_source, "ipv4acd-receive-message"); r = ipv4acd_set_next_wakeup(ll, 0, 0); if (r < 0) -- cgit v1.2.3-54-g00ecf From d246e77a4343ff8a0266fc7dd5a7de5c524f9e44 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 17:52:08 +0200 Subject: ipv4acd: rename ipv4acd_stop() → ipv4acd_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is much less confusing, since there's also sd_ipv4acd_stop(), which was idfferent from ipv4acd_stop(). After renaming it, let's also use the funciton when destroying ipv4acd objects, as the code is pretty much the same for that. --- src/libsystemd-network/sd-ipv4acd.c | 94 +++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 51 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 7393be45f5..163d0f9199 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -34,6 +34,7 @@ #include "list.h" #include "random-util.h" #include "siphash24.h" +#include "string-util.h" #include "util.h" /* Constants from the RFC */ @@ -90,6 +91,29 @@ struct sd_ipv4acd { void* userdata; }; +static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counter) { + assert(ll); + assert(st < _IPV4ACD_STATE_MAX); + + if (st == ll->state && !reset_counter) + ll->n_iteration++; + else { + ll->state = st; + ll->n_iteration = 0; + } +} + +static void ipv4acd_reset(sd_ipv4acd *ll) { + assert(ll); + + ll->timer_event_source = sd_event_source_unref(ll->timer_event_source); + ll->receive_message_event_source = sd_event_source_unref(ll->receive_message_event_source); + + ll->fd = safe_close(ll->fd); + + ipv4acd_set_state(ll, IPV4ACD_STATE_INIT, true); +} + sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *ll) { if (!ll) return NULL; @@ -110,11 +134,7 @@ sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *ll) { if (ll->n_ref > 0) return NULL; - ll->timer_event_source = sd_event_source_unref(ll->timer_event_source); - ll->receive_message_event_source = sd_event_source_unref(ll->receive_message_event_source); - - ll->fd = safe_close(ll->fd); - + ipv4acd_reset(ll); sd_ipv4acd_detach_event(ll); free(ll); @@ -142,18 +162,6 @@ int sd_ipv4acd_new(sd_ipv4acd **ret) { return 0; } -static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counter) { - assert(ll); - assert(st < _IPV4ACD_STATE_MAX); - - if (st == ll->state && !reset_counter) - ll->n_iteration++; - else { - ll->state = st; - ll->n_iteration = 0; - } -} - static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) { assert(ll); @@ -163,23 +171,13 @@ static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) { ll->callback(ll, event, ll->userdata); } -static void ipv4acd_stop(sd_ipv4acd *ll) { - assert(ll); - - ll->timer_event_source = sd_event_source_unref(ll->timer_event_source); +int sd_ipv4acd_stop(sd_ipv4acd *ll) { + assert_return(ll, -EINVAL); - ll->receive_message_event_source = sd_event_source_unref(ll->receive_message_event_source); - ll->fd = safe_close(ll->fd); + ipv4acd_reset(ll); log_ipv4acd(ll, "STOPPED"); - ipv4acd_set_state(ll, IPV4ACD_STATE_INIT, true); -} - -int sd_ipv4acd_stop(sd_ipv4acd *ll) { - assert_return(ll, -EINVAL); - - ipv4acd_stop(ll); ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_STOP); return 0; @@ -272,9 +270,8 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) _cleanup_free_ char *address = NULL; union in_addr_union addr = { .in.s_addr = ll->address }; - r = in_addr_to_string(AF_INET, &addr, &address); - if (r >= 0) - log_ipv4acd(ll, "Probing %s", address); + (void) in_addr_to_string(AF_INET, &addr, &address); + log_ipv4acd(ll, "Probing %s", strna(address)); } if (ll->n_iteration < PROBE_NUM - 2) { @@ -337,18 +334,15 @@ out: static void ipv4acd_on_conflict(sd_ipv4acd *ll) { _cleanup_free_ char *address = NULL; union in_addr_union addr = { .in.s_addr = ll->address }; - int r; assert(ll); ll->n_conflict++; - r = in_addr_to_string(AF_INET, &addr, &address); - if (r >= 0) - log_ipv4acd(ll, "Conflict on %s (%u)", address, ll->n_conflict); - - ipv4acd_stop(ll); + (void) in_addr_to_string(AF_INET, &addr, &address); + log_ipv4acd(ll, "Conflict on %s (%u)", strna(address), ll->n_conflict); + ipv4acd_reset(ll); ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_CONFLICT); } @@ -505,33 +499,31 @@ int sd_ipv4acd_start(sd_ipv4acd *ll) { assert_return(!ether_addr_is_null(&ll->mac_addr), -EINVAL); assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); - ll->defend_window = 0; - r = arp_network_bind_raw_socket(ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) - goto out; + return r; - ll->fd = safe_close(ll->fd); + safe_close(ll->fd); ll->fd = r; + ll->defend_window = 0; r = sd_event_add_io(ll->event, &ll->receive_message_event_source, ll->fd, EPOLLIN, ipv4acd_on_packet, ll); if (r < 0) - goto out; + goto fail; r = sd_event_source_set_priority(ll->receive_message_event_source, ll->event_priority); if (r < 0) - goto out; + goto fail; (void) sd_event_source_set_description(ll->receive_message_event_source, "ipv4acd-receive-message"); r = ipv4acd_set_next_wakeup(ll, 0, 0); if (r < 0) - goto out; -out: - if (r < 0) { - ipv4acd_stop(ll); - return r; - } + goto fail; return 0; + +fail: + ipv4acd_reset(ll); + return r; } -- cgit v1.2.3-54-g00ecf From c9e458a419ae8961a27cea19d0a15b7058a132f9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 18:06:33 +0200 Subject: ipv4acd: introduce new "started" state This state is active immediately after the state engine was started, but before the first timer hits. This way multiple _start() invocations on the same object are always detected correctly. --- src/libsystemd-network/sd-ipv4acd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 163d0f9199..59b87f42b7 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -57,6 +57,7 @@ typedef enum IPv4ACDState { IPV4ACD_STATE_INIT, + IPV4ACD_STATE_STARTED, IPV4ACD_STATE_WAITING_PROBE, IPV4ACD_STATE_PROBING, IPV4ACD_STATE_WAITING_ANNOUNCE, @@ -240,7 +241,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) switch (ll->state) { - case IPV4ACD_STATE_INIT: + case IPV4ACD_STATE_STARTED: ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_PROBE, true); if (ll->n_conflict >= MAX_CONFLICTS) { @@ -521,6 +522,7 @@ int sd_ipv4acd_start(sd_ipv4acd *ll) { if (r < 0) goto fail; + ipv4acd_set_state(ll, IPV4ACD_STATE_STARTED, true); return 0; fail: -- cgit v1.2.3-54-g00ecf From d914f7a5639b72a400472dda622280f1015b6866 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 18:07:42 +0200 Subject: ipv4acd: no need to memcpy() where assignment suffices --- src/libsystemd-network/sd-ipv4acd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 59b87f42b7..12003fb796 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -433,7 +433,7 @@ int sd_ipv4acd_set_mac(sd_ipv4acd *ll, const struct ether_addr *addr) { assert_return(addr, -EINVAL); assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); - memcpy(&ll->mac_addr, addr, ETH_ALEN); + ll->mac_addr = *addr; return 0; } -- cgit v1.2.3-54-g00ecf From d63458452dabeb59665c316693df07e90b9a9395 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 18:07:51 +0200 Subject: ipv4acd: in case the state engine is reused, reset n_conflict timer to 0 --- src/libsystemd-network/sd-ipv4acd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 12003fb796..99505181a4 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -507,6 +507,7 @@ int sd_ipv4acd_start(sd_ipv4acd *ll) { safe_close(ll->fd); ll->fd = r; ll->defend_window = 0; + ll->n_conflict = 0; r = sd_event_add_io(ll->event, &ll->receive_message_event_source, ll->fd, EPOLLIN, ipv4acd_on_packet, ll); if (r < 0) -- cgit v1.2.3-54-g00ecf From e3f4eedba14f6485ef40bc87624d3b617f1b6ac7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 18:18:04 +0200 Subject: ipv4acd: normalize time types to usec_t We try to stick to usec_t for encoding time information, do that here too. In particular, get rid of "int" second specifications, since signed timespans are a weird thing. --- src/libsystemd-network/sd-ipv4acd.c | 51 +++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 27 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 99505181a4..f5b8fb2c0a 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -38,16 +38,16 @@ #include "util.h" /* Constants from the RFC */ -#define PROBE_WAIT 1 -#define PROBE_NUM 3 -#define PROBE_MIN 1 -#define PROBE_MAX 2 -#define ANNOUNCE_WAIT 2 -#define ANNOUNCE_NUM 2 -#define ANNOUNCE_INTERVAL 2 -#define MAX_CONFLICTS 10 -#define RATE_LIMIT_INTERVAL 60 -#define DEFEND_INTERVAL 10 +#define PROBE_WAIT_USEC (1U * USEC_PER_SEC) +#define PROBE_NUM 3U +#define PROBE_MIN_USEC (1U * USEC_PER_SEC) +#define PROBE_MAX_USEC (2U * USEC_PER_SEC) +#define ANNOUNCE_WAIT_USEC (2U * USEC_PER_SEC) +#define ANNOUNCE_NUM 2U +#define ANNOUNCE_INTERVAL_USEC (2U * USEC_PER_SEC) +#define MAX_CONFLICTS 10U +#define RATE_LIMIT_INTERVAL_USEC (60U * USEC_PER_SEC) +#define DEFEND_INTERVAL_USEC (10U * USEC_PER_SEC) #define IPV4ACD_NETWORK 0xA9FE0000UL #define IPV4ACD_NETMASK 0xFFFF0000UL @@ -186,25 +186,21 @@ int sd_ipv4acd_stop(sd_ipv4acd *ll) { static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata); -static int ipv4acd_set_next_wakeup(sd_ipv4acd *ll, int sec, int random_sec) { +static int ipv4acd_set_next_wakeup(sd_ipv4acd *ll, usec_t usec, usec_t random_usec) { _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL; - usec_t next_timeout; - usec_t time_now; + usec_t next_timeout, time_now; int r; - assert(sec >= 0); - assert(random_sec >= 0); assert(ll); - next_timeout = sec * USEC_PER_SEC; + next_timeout = usec; - if (random_sec) - next_timeout += random_u32() % (random_sec * USEC_PER_SEC); + if (random_usec > 0) + next_timeout += (usec_t) random_u64() % random_usec; assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) >= 0); - r = sd_event_add_time(ll->event, &timer, clock_boottime_or_monotonic(), - time_now + next_timeout, 0, ipv4acd_on_timeout, ll); + r = sd_event_add_time(ll->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, ll); if (r < 0) return r; @@ -245,15 +241,16 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_PROBE, true); if (ll->n_conflict >= MAX_CONFLICTS) { - log_ipv4acd(ll, "Max conflicts reached, delaying by %us", RATE_LIMIT_INTERVAL); + char ts[FORMAT_TIMESPAN_MAX]; + log_ipv4acd(ll, "Max conflicts reached, delaying by %s", format_timespan(ts, sizeof(ts), RATE_LIMIT_INTERVAL_USEC, 0)); - r = ipv4acd_set_next_wakeup(ll, RATE_LIMIT_INTERVAL, PROBE_WAIT); + r = ipv4acd_set_next_wakeup(ll, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC); if (r < 0) goto out; ll->n_conflict = 0; } else { - r = ipv4acd_set_next_wakeup(ll, 0, PROBE_WAIT); + r = ipv4acd_set_next_wakeup(ll, 0, PROBE_WAIT_USEC); if (r < 0) goto out; } @@ -278,13 +275,13 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) if (ll->n_iteration < PROBE_NUM - 2) { ipv4acd_set_state(ll, IPV4ACD_STATE_PROBING, false); - r = ipv4acd_set_next_wakeup(ll, PROBE_MIN, (PROBE_MAX-PROBE_MIN)); + r = ipv4acd_set_next_wakeup(ll, PROBE_MIN_USEC, (PROBE_MAX_USEC-PROBE_MIN_USEC)); if (r < 0) goto out; } else { ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_ANNOUNCE, true); - r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_WAIT, 0); + r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_WAIT_USEC, 0); if (r < 0) goto out; } @@ -310,7 +307,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) ipv4acd_set_state(ll, IPV4ACD_STATE_ANNOUNCING, false); - r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_INTERVAL, 0); + r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_INTERVAL_USEC, 0); if (r < 0) goto out; @@ -387,7 +384,7 @@ static int ipv4acd_on_packet( /* Defend address */ if (ts > ll->defend_window) { - ll->defend_window = ts + DEFEND_INTERVAL * USEC_PER_SEC; + ll->defend_window = ts + DEFEND_INTERVAL_USEC; r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { log_ipv4acd_errno(ll, r, "Failed to send ARP announcement: %m"); -- cgit v1.2.3-54-g00ecf From ff0c5ebd4a29be137080021f741b072d4c44b1a9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 18:26:49 +0200 Subject: ipv4acd: make sure our event handler callbacks never check uninitialized "r" for errors --- src/libsystemd-network/sd-ipv4acd.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index f5b8fb2c0a..31a05ae6dc 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -246,13 +246,13 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) r = ipv4acd_set_next_wakeup(ll, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC); if (r < 0) - goto out; + goto fail; ll->n_conflict = 0; } else { r = ipv4acd_set_next_wakeup(ll, 0, PROBE_WAIT_USEC); if (r < 0) - goto out; + goto fail; } break; @@ -263,7 +263,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) r = arp_send_probe(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { log_ipv4acd_errno(ll, r, "Failed to send ARP probe: %m"); - goto out; + goto fail; } else { _cleanup_free_ char *address = NULL; union in_addr_union addr = { .in.s_addr = ll->address }; @@ -277,13 +277,13 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) r = ipv4acd_set_next_wakeup(ll, PROBE_MIN_USEC, (PROBE_MAX_USEC-PROBE_MIN_USEC)); if (r < 0) - goto out; + goto fail; } else { ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_ANNOUNCE, true); r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_WAIT_USEC, 0); if (r < 0) - goto out; + goto fail; } break; @@ -301,7 +301,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { log_ipv4acd_errno(ll, r, "Failed to send ARP announcement: %m"); - goto out; + goto fail; } else log_ipv4acd(ll, "ANNOUNCE"); @@ -309,7 +309,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_INTERVAL_USEC, 0); if (r < 0) - goto out; + goto fail; if (ll->n_iteration == 0) { ll->n_conflict = 0; @@ -322,11 +322,11 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) assert_not_reached("Invalid state."); } -out: - if (r < 0) - sd_ipv4acd_stop(ll); + return 0; - return 1; +fail: + sd_ipv4acd_stop(ll); + return 0; } static void ipv4acd_on_conflict(sd_ipv4acd *ll) { @@ -364,8 +364,8 @@ static int ipv4acd_on_packet( if (errno == EAGAIN || errno == EINTR) return 0; - r = log_ipv4acd_errno(ll, errno, "Failed to read ARP packet: %m"); - goto out; + log_ipv4acd_errno(ll, errno, "Failed to read ARP packet: %m"); + goto fail; } if ((size_t) n != sizeof(struct ether_arp)) { log_ipv4acd(ll, "Ignoring too short ARP packet."); @@ -388,7 +388,7 @@ static int ipv4acd_on_packet( r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); if (r < 0) { log_ipv4acd_errno(ll, r, "Failed to send ARP announcement: %m"); - goto out; + goto fail; } else log_ipv4acd(ll, "DEFEND"); @@ -408,11 +408,11 @@ static int ipv4acd_on_packet( assert_not_reached("Invalid state."); } -out: - if (r < 0) - sd_ipv4acd_stop(ll); + return 0; - return 1; +fail: + sd_ipv4acd_stop(ll); + return 0; } int sd_ipv4acd_set_ifindex(sd_ipv4acd *ll, int ifindex) { -- cgit v1.2.3-54-g00ecf From 38958cd66e87037c75109408bf4093be21811eba Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 18:33:17 +0200 Subject: ipv4ll: change "seed" parameter to be uint64_t Let's make clear this always has the same size, since otherwise it's not useful for reproducible runs, which this is really about however. --- src/libsystemd-network/sd-ipv4ll.c | 8 +++----- src/libsystemd-network/test-ipv4ll.c | 2 +- src/network/networkd-ipv4ll.c | 4 +--- src/systemd/sd-ipv4ll.h | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index 1f6da4bb16..0e6a9df9e5 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -144,9 +144,7 @@ int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) { /* If no random data is set, generate some from the MAC */ seed = siphash24(&addr->ether_addr_octet, ETH_ALEN, HASH_KEY.bytes); - assert_cc(sizeof(unsigned) <= 8); - - r = sd_ipv4ll_set_address_seed(ll, (unsigned) htole64(seed)); + r = sd_ipv4ll_set_address_seed(ll, htole64(seed)); if (r < 0) return r; } @@ -187,7 +185,7 @@ int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address) { return 0; } -int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, unsigned seed) { +int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed) { _cleanup_free_ struct random_data *random_data = NULL; _cleanup_free_ char *random_data_state = NULL; int r; @@ -202,7 +200,7 @@ int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, unsigned seed) { if (!random_data_state) return -ENOMEM; - r = initstate_r(seed, random_data_state, 128, random_data); + r = initstate_r((unsigned) seed, random_data_state, 128, random_data); if (r < 0) return r; diff --git a/src/libsystemd-network/test-ipv4ll.c b/src/libsystemd-network/test-ipv4ll.c index aad3c476a0..fe70697075 100644 --- a/src/libsystemd-network/test-ipv4ll.c +++ b/src/libsystemd-network/test-ipv4ll.c @@ -101,7 +101,7 @@ int arp_network_bind_raw_socket(int index, be32_t address, const struct ether_ad static void test_public_api_setters(sd_event *e) { struct in_addr address = {}; - unsigned seed = 0; + uint64_t seed = 0; sd_ipv4ll *ll; struct ether_addr mac_addr = { .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}}; diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index a41f231f8c..735c231a4c 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -215,9 +215,7 @@ int ipv4ll_configure(Link *link) { if (link->udev_device) { r = net_get_unique_predictable_data(link->udev_device, &seed); if (r >= 0) { - assert_cc(sizeof(unsigned) <= 8); - - r = sd_ipv4ll_set_address_seed(link->ipv4ll, (unsigned)seed); + r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed); if (r < 0) return r; } diff --git a/src/systemd/sd-ipv4ll.h b/src/systemd/sd-ipv4ll.h index 4682dd6605..1109ec52e0 100644 --- a/src/systemd/sd-ipv4ll.h +++ b/src/systemd/sd-ipv4ll.h @@ -45,7 +45,7 @@ int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdat int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr); int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int interface_index); int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address); -int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, unsigned seed); +int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed); int sd_ipv4ll_is_running(sd_ipv4ll *ll); int sd_ipv4ll_start(sd_ipv4ll *ll); int sd_ipv4ll_stop(sd_ipv4ll *ll); -- cgit v1.2.3-54-g00ecf From 96a7979f3d77d1e629dcfe5ee018d18c281771a1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 19:24:21 +0200 Subject: ipv4acd: rework how we pick ipv4ll addresses Let's make the seed actually work as stable seed, and use siphash24 to generate the series of addresses, instead of the opaque libc random_r(). This not only makes the seed truly work as stable, portable seed, but also makes the code quite a bit shorter, and removes a couple of memory allocations. --- src/libsystemd-network/sd-ipv4ll.c | 131 +++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 70 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index 0e6a9df9e5..4fcb06a308 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -28,6 +28,7 @@ #include "sd-ipv4ll.h" #include "alloc-util.h" +#include "ether-addr-util.h" #include "in-addr-util.h" #include "list.h" #include "random-util.h" @@ -35,8 +36,8 @@ #include "sparse-endian.h" #include "util.h" -#define IPV4LL_NETWORK 0xA9FE0000UL -#define IPV4LL_NETMASK 0xFFFF0000UL +#define IPV4LL_NETWORK UINT32_C(0xA9FE0000) +#define IPV4LL_NETMASK UINT32_C(0xFFFF0000) #define IPV4LL_DONT_DESTROY(ll) \ _cleanup_(sd_ipv4ll_unrefp) _unused_ sd_ipv4ll *_dont_destroy_##ll = sd_ipv4ll_ref(ll) @@ -45,16 +46,25 @@ struct sd_ipv4ll { unsigned n_ref; sd_ipv4acd *acd; + be32_t address; /* the address pushed to ACD */ - struct random_data *random_data; - char *random_data_state; + struct ether_addr mac; + + struct { + le64_t value; + le64_t generation; + } seed; + bool seed_set; /* External */ be32_t claimed_address; + sd_ipv4ll_callback_t callback; void* userdata; }; +static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata); + sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) { if (!ll) return NULL; @@ -76,16 +86,11 @@ sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) { return NULL; sd_ipv4acd_unref(ll->acd); - - free(ll->random_data); - free(ll->random_data_state); free(ll); return NULL; } -static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata); - int sd_ipv4ll_new(sd_ipv4ll **ret) { _cleanup_(sd_ipv4ll_unrefp) sd_ipv4ll *ll = NULL; int r; @@ -113,43 +118,32 @@ int sd_ipv4ll_new(sd_ipv4ll **ret) { } int sd_ipv4ll_stop(sd_ipv4ll *ll) { - int r; - assert_return(ll, -EINVAL); - r = sd_ipv4acd_stop(ll->acd); - if (r < 0) - return r; - - return 0; + return sd_ipv4acd_stop(ll->acd); } int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int ifindex) { assert_return(ll, -EINVAL); assert_return(ifindex > 0, -EINVAL); + assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY); return sd_ipv4acd_set_ifindex(ll->acd, ifindex); } -#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2) - int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) { int r; assert_return(ll, -EINVAL); + assert_return(addr, -EINVAL); + assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY); - if (!ll->random_data) { - uint64_t seed; - - /* If no random data is set, generate some from the MAC */ - seed = siphash24(&addr->ether_addr_octet, ETH_ALEN, HASH_KEY.bytes); - - r = sd_ipv4ll_set_address_seed(ll, htole64(seed)); - if (r < 0) - return r; - } + r = sd_ipv4acd_set_mac(ll->acd, addr); + if (r < 0) + return r; - return sd_ipv4acd_set_mac(ll->acd, addr); + ll->mac = *addr; + return 0; } int sd_ipv4ll_detach_event(sd_ipv4ll *ll) { @@ -186,31 +180,11 @@ int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address) { } int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed) { - _cleanup_free_ struct random_data *random_data = NULL; - _cleanup_free_ char *random_data_state = NULL; - int r; - assert_return(ll, -EINVAL); + assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY); - random_data = new0(struct random_data, 1); - if (!random_data) - return -ENOMEM; - - random_data_state = new0(char, 128); - if (!random_data_state) - return -ENOMEM; - - r = initstate_r((unsigned) seed, random_data_state, 128, random_data); - if (r < 0) - return r; - - free(ll->random_data); - ll->random_data = random_data; - random_data = NULL; - - free(ll->random_data_state); - ll->random_data_state = random_data_state; - random_data_state = NULL; + ll->seed.value = htole64(seed); + ll->seed_set = true; return 0; } @@ -254,48 +228,64 @@ int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address) { return 0; } +#define PICK_HASH_KEY SD_ID128_MAKE(15,ac,82,a6,d6,3f,49,78,98,77,5d,0c,69,02,94,0b) + static int ipv4ll_pick_address(sd_ipv4ll *ll) { - struct in_addr in_addr; be32_t addr; - int r; - int32_t random; assert(ll); - assert(ll->random_data); do { - r = random_r(ll->random_data, &random); - if (r < 0) - return r; - addr = htobe32((random & 0x0000FFFF) | IPV4LL_NETWORK); - } while (addr == ll->address || - (ntohl(addr) & 0x0000FF00) == 0x0000 || - (ntohl(addr) & 0x0000FF00) == 0xFF00); + uint64_t h; - in_addr.s_addr = addr; + h = siphash24(&ll->seed, sizeof(ll->seed), PICK_HASH_KEY.bytes); - r = sd_ipv4ll_set_address(ll, &in_addr); - if (r < 0) - return r; + /* Increase the generation counter by one */ + ll->seed.generation = htole64(le64toh(ll->seed.generation) + 1); - return 0; + addr = htobe32((h & UINT32_C(0x0000FFFF)) | IPV4LL_NETWORK); + } while (addr == ll->address || + (be32toh(addr) & 0x0000FF00) == 0x0000 || + (be32toh(addr) & 0x0000FF00) == 0xFF00); + + return sd_ipv4ll_set_address(ll, &(struct in_addr) { addr }); } +#define MAC_HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2) + int sd_ipv4ll_start(sd_ipv4ll *ll) { int r; + bool picked_address = false; assert_return(ll, -EINVAL); - assert_return(ll->random_data, -EINVAL); + assert_return(!ether_addr_is_null(&ll->mac), -EINVAL); + assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY); + + /* If no random seed is set, generate some from the MAC address */ + if (!ll->seed_set) + ll->seed.value = htole64(siphash24(ll->mac.ether_addr_octet, ETH_ALEN, MAC_HASH_KEY.bytes)); + + /* Restart the generation counter. */ + ll->seed.generation = 0; if (ll->address == 0) { r = ipv4ll_pick_address(ll); if (r < 0) return r; + + picked_address = true; } r = sd_ipv4acd_start(ll->acd); - if (r < 0) + if (r < 0) { + + /* We couldn't start? If so, let's forget the picked address again, the user might make a change and + * retry, and we want the new data to take effect when picking an address. */ + if (picked_address) + ll->address = 0; + return r; + } return 0; } @@ -345,6 +335,7 @@ void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) { } break; + default: assert_not_reached("Invalid IPv4ACD event."); } -- cgit v1.2.3-54-g00ecf From 3aacc173e92126c3c9006aa163a2848c6523fd28 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 19:35:18 +0200 Subject: sd-ipv4acd: drop IPV4ACD_NETWORK definition Appears to be a copy/paste mistake from sd-ipv4ll. Let's get rid of this. --- src/libsystemd-network/sd-ipv4acd.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 31a05ae6dc..a4d57bd964 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -49,12 +49,6 @@ #define RATE_LIMIT_INTERVAL_USEC (60U * USEC_PER_SEC) #define DEFEND_INTERVAL_USEC (10U * USEC_PER_SEC) -#define IPV4ACD_NETWORK 0xA9FE0000UL -#define IPV4ACD_NETMASK 0xFFFF0000UL - -#define log_ipv4acd_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "ACD: " fmt, ##__VA_ARGS__) -#define log_ipv4acd(ll, fmt, ...) log_ipv4acd_errno(ll, 0, fmt, ##__VA_ARGS__) - typedef enum IPv4ACDState { IPV4ACD_STATE_INIT, IPV4ACD_STATE_STARTED, @@ -92,6 +86,9 @@ struct sd_ipv4acd { void* userdata; }; +#define log_ipv4acd_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__) +#define log_ipv4acd(ll, fmt, ...) log_ipv4acd_errno(ll, 0, fmt, ##__VA_ARGS__) + static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counter) { assert(ll); assert(st < _IPV4ACD_STATE_MAX); -- cgit v1.2.3-54-g00ecf From 703945c1dcf2e46e5bf48427c7b23f5d90b6d53b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 19:35:54 +0200 Subject: sd-ipv4ll: add a bit of logging to IPv4LL too --- src/libsystemd-network/sd-ipv4ll.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index 4fcb06a308..cba9a89b76 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -34,6 +34,7 @@ #include "random-util.h" #include "siphash24.h" #include "sparse-endian.h" +#include "string-util.h" #include "util.h" #define IPV4LL_NETWORK UINT32_C(0xA9FE0000) @@ -63,6 +64,9 @@ struct sd_ipv4ll { void* userdata; }; +#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__) +#define log_ipv4ll(ll, fmt, ...) log_ipv4ll_errno(ll, 0, fmt, ##__VA_ARGS__) + static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata); sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) { @@ -231,6 +235,7 @@ int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address) { #define PICK_HASH_KEY SD_ID128_MAKE(15,ac,82,a6,d6,3f,49,78,98,77,5d,0c,69,02,94,0b) static int ipv4ll_pick_address(sd_ipv4ll *ll) { + _cleanup_free_ char *address = NULL; be32_t addr; assert(ll); @@ -248,6 +253,9 @@ static int ipv4ll_pick_address(sd_ipv4ll *ll) { (be32toh(addr) & 0x0000FF00) == 0x0000 || (be32toh(addr) & 0x0000FF00) == 0xFF00); + (void) in_addr_to_string(AF_INET, &(union in_addr_union) { .in.s_addr = addr }, &address); + log_ipv4ll(ll, "Picked new IP address %s.", strna(address)); + return sd_ipv4ll_set_address(ll, &(struct in_addr) { addr }); } -- cgit v1.2.3-54-g00ecf From b24ef0493abec10435f43c4ce3791f625bad97f4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2016 19:39:44 +0200 Subject: ipv4acd: rename "ll" parameter to "acd" everywhere Appears to be a (confusing) left-over from copy/paste when this still was ipv4ll code. --- src/libsystemd-network/sd-ipv4acd.c | 304 ++++++++++++++++++------------------ src/systemd/sd-ipv4acd.h | 28 ++-- 2 files changed, 166 insertions(+), 166 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index a4d57bd964..662885840f 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -86,140 +86,140 @@ struct sd_ipv4acd { void* userdata; }; -#define log_ipv4acd_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__) -#define log_ipv4acd(ll, fmt, ...) log_ipv4acd_errno(ll, 0, fmt, ##__VA_ARGS__) +#define log_ipv4acd_errno(acd, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__) +#define log_ipv4acd(acd, fmt, ...) log_ipv4acd_errno(acd, 0, fmt, ##__VA_ARGS__) -static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counter) { - assert(ll); +static void ipv4acd_set_state(sd_ipv4acd *acd, IPv4ACDState st, bool reset_counter) { + assert(acd); assert(st < _IPV4ACD_STATE_MAX); - if (st == ll->state && !reset_counter) - ll->n_iteration++; + if (st == acd->state && !reset_counter) + acd->n_iteration++; else { - ll->state = st; - ll->n_iteration = 0; + acd->state = st; + acd->n_iteration = 0; } } -static void ipv4acd_reset(sd_ipv4acd *ll) { - assert(ll); +static void ipv4acd_reset(sd_ipv4acd *acd) { + assert(acd); - ll->timer_event_source = sd_event_source_unref(ll->timer_event_source); - ll->receive_message_event_source = sd_event_source_unref(ll->receive_message_event_source); + acd->timer_event_source = sd_event_source_unref(acd->timer_event_source); + acd->receive_message_event_source = sd_event_source_unref(acd->receive_message_event_source); - ll->fd = safe_close(ll->fd); + acd->fd = safe_close(acd->fd); - ipv4acd_set_state(ll, IPV4ACD_STATE_INIT, true); + ipv4acd_set_state(acd, IPV4ACD_STATE_INIT, true); } -sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *ll) { - if (!ll) +sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd) { + if (!acd) return NULL; - assert_se(ll->n_ref >= 1); - ll->n_ref++; + assert_se(acd->n_ref >= 1); + acd->n_ref++; - return ll; + return acd; } -sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *ll) { - if (!ll) +sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd) { + if (!acd) return NULL; - assert_se(ll->n_ref >= 1); - ll->n_ref--; + assert_se(acd->n_ref >= 1); + acd->n_ref--; - if (ll->n_ref > 0) + if (acd->n_ref > 0) return NULL; - ipv4acd_reset(ll); - sd_ipv4acd_detach_event(ll); + ipv4acd_reset(acd); + sd_ipv4acd_detach_event(acd); - free(ll); + free(acd); return NULL; } int sd_ipv4acd_new(sd_ipv4acd **ret) { - _cleanup_(sd_ipv4acd_unrefp) sd_ipv4acd *ll = NULL; + _cleanup_(sd_ipv4acd_unrefp) sd_ipv4acd *acd = NULL; assert_return(ret, -EINVAL); - ll = new0(sd_ipv4acd, 1); - if (!ll) + acd = new0(sd_ipv4acd, 1); + if (!acd) return -ENOMEM; - ll->n_ref = 1; - ll->state = IPV4ACD_STATE_INIT; - ll->ifindex = -1; - ll->fd = -1; + acd->n_ref = 1; + acd->state = IPV4ACD_STATE_INIT; + acd->ifindex = -1; + acd->fd = -1; - *ret = ll; - ll = NULL; + *ret = acd; + acd = NULL; return 0; } -static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) { - assert(ll); +static void ipv4acd_client_notify(sd_ipv4acd *acd, int event) { + assert(acd); - if (!ll->callback) + if (!acd->callback) return; - ll->callback(ll, event, ll->userdata); + acd->callback(acd, event, acd->userdata); } -int sd_ipv4acd_stop(sd_ipv4acd *ll) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_stop(sd_ipv4acd *acd) { + assert_return(acd, -EINVAL); - ipv4acd_reset(ll); + ipv4acd_reset(acd); - log_ipv4acd(ll, "STOPPED"); + log_ipv4acd(acd, "STOPPED"); - ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_STOP); + ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_STOP); return 0; } static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata); -static int ipv4acd_set_next_wakeup(sd_ipv4acd *ll, usec_t usec, usec_t random_usec) { +static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_usec) { _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL; usec_t next_timeout, time_now; int r; - assert(ll); + assert(acd); next_timeout = usec; if (random_usec > 0) next_timeout += (usec_t) random_u64() % random_usec; - assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) >= 0); + assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &time_now) >= 0); - r = sd_event_add_time(ll->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, ll); + r = sd_event_add_time(acd->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, acd); if (r < 0) return r; - r = sd_event_source_set_priority(timer, ll->event_priority); + r = sd_event_source_set_priority(timer, acd->event_priority); if (r < 0) return r; (void) sd_event_source_set_description(timer, "ipv4acd-timer"); - sd_event_source_unref(ll->timer_event_source); - ll->timer_event_source = timer; + sd_event_source_unref(acd->timer_event_source); + acd->timer_event_source = timer; timer = NULL; return 0; } -static bool ipv4acd_arp_conflict(sd_ipv4acd *ll, struct ether_arp *arp) { - assert(ll); +static bool ipv4acd_arp_conflict(sd_ipv4acd *acd, struct ether_arp *arp) { + assert(acd); assert(arp); /* see the BPF */ - if (memcmp(arp->arp_spa, &ll->address, sizeof(ll->address)) == 0) + if (memcmp(arp->arp_spa, &acd->address, sizeof(acd->address)) == 0) return true; /* the TPA matched instead of the SPA, this is not a conflict */ @@ -227,27 +227,27 @@ static bool ipv4acd_arp_conflict(sd_ipv4acd *ll, struct ether_arp *arp) { } static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) { - sd_ipv4acd *ll = userdata; + sd_ipv4acd *acd = userdata; int r = 0; - assert(ll); + assert(acd); - switch (ll->state) { + switch (acd->state) { case IPV4ACD_STATE_STARTED: - ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_PROBE, true); + ipv4acd_set_state(acd, IPV4ACD_STATE_WAITING_PROBE, true); - if (ll->n_conflict >= MAX_CONFLICTS) { + if (acd->n_conflict >= MAX_CONFLICTS) { char ts[FORMAT_TIMESPAN_MAX]; - log_ipv4acd(ll, "Max conflicts reached, delaying by %s", format_timespan(ts, sizeof(ts), RATE_LIMIT_INTERVAL_USEC, 0)); + log_ipv4acd(acd, "Max conflicts reached, delaying by %s", format_timespan(ts, sizeof(ts), RATE_LIMIT_INTERVAL_USEC, 0)); - r = ipv4acd_set_next_wakeup(ll, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC); + r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC); if (r < 0) goto fail; - ll->n_conflict = 0; + acd->n_conflict = 0; } else { - r = ipv4acd_set_next_wakeup(ll, 0, PROBE_WAIT_USEC); + r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC); if (r < 0) goto fail; } @@ -257,28 +257,28 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) case IPV4ACD_STATE_WAITING_PROBE: case IPV4ACD_STATE_PROBING: /* Send a probe */ - r = arp_send_probe(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); + r = arp_send_probe(acd->fd, acd->ifindex, acd->address, &acd->mac_addr); if (r < 0) { - log_ipv4acd_errno(ll, r, "Failed to send ARP probe: %m"); + log_ipv4acd_errno(acd, r, "Failed to send ARP probe: %m"); goto fail; } else { _cleanup_free_ char *address = NULL; - union in_addr_union addr = { .in.s_addr = ll->address }; + union in_addr_union addr = { .in.s_addr = acd->address }; (void) in_addr_to_string(AF_INET, &addr, &address); - log_ipv4acd(ll, "Probing %s", strna(address)); + log_ipv4acd(acd, "Probing %s", strna(address)); } - if (ll->n_iteration < PROBE_NUM - 2) { - ipv4acd_set_state(ll, IPV4ACD_STATE_PROBING, false); + if (acd->n_iteration < PROBE_NUM - 2) { + ipv4acd_set_state(acd, IPV4ACD_STATE_PROBING, false); - r = ipv4acd_set_next_wakeup(ll, PROBE_MIN_USEC, (PROBE_MAX_USEC-PROBE_MIN_USEC)); + r = ipv4acd_set_next_wakeup(acd, PROBE_MIN_USEC, (PROBE_MAX_USEC-PROBE_MIN_USEC)); if (r < 0) goto fail; } else { - ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_ANNOUNCE, true); + ipv4acd_set_state(acd, IPV4ACD_STATE_WAITING_ANNOUNCE, true); - r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_WAIT_USEC, 0); + r = ipv4acd_set_next_wakeup(acd, ANNOUNCE_WAIT_USEC, 0); if (r < 0) goto fail; } @@ -286,8 +286,8 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) break; case IPV4ACD_STATE_ANNOUNCING: - if (ll->n_iteration >= ANNOUNCE_NUM - 1) { - ipv4acd_set_state(ll, IPV4ACD_STATE_RUNNING, false); + if (acd->n_iteration >= ANNOUNCE_NUM - 1) { + ipv4acd_set_state(acd, IPV4ACD_STATE_RUNNING, false); break; } @@ -295,22 +295,22 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) case IPV4ACD_STATE_WAITING_ANNOUNCE: /* Send announcement packet */ - r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); + r = arp_send_announcement(acd->fd, acd->ifindex, acd->address, &acd->mac_addr); if (r < 0) { - log_ipv4acd_errno(ll, r, "Failed to send ARP announcement: %m"); + log_ipv4acd_errno(acd, r, "Failed to send ARP announcement: %m"); goto fail; } else - log_ipv4acd(ll, "ANNOUNCE"); + log_ipv4acd(acd, "ANNOUNCE"); - ipv4acd_set_state(ll, IPV4ACD_STATE_ANNOUNCING, false); + ipv4acd_set_state(acd, IPV4ACD_STATE_ANNOUNCING, false); - r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_INTERVAL_USEC, 0); + r = ipv4acd_set_next_wakeup(acd, ANNOUNCE_INTERVAL_USEC, 0); if (r < 0) goto fail; - if (ll->n_iteration == 0) { - ll->n_conflict = 0; - ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_BIND); + if (acd->n_iteration == 0) { + acd->n_conflict = 0; + ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_BIND); } break; @@ -322,23 +322,23 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) return 0; fail: - sd_ipv4acd_stop(ll); + sd_ipv4acd_stop(acd); return 0; } -static void ipv4acd_on_conflict(sd_ipv4acd *ll) { +static void ipv4acd_on_conflict(sd_ipv4acd *acd) { _cleanup_free_ char *address = NULL; - union in_addr_union addr = { .in.s_addr = ll->address }; + union in_addr_union addr = { .in.s_addr = acd->address }; - assert(ll); + assert(acd); - ll->n_conflict++; + acd->n_conflict++; (void) in_addr_to_string(AF_INET, &addr, &address); - log_ipv4acd(ll, "Conflict on %s (%u)", strna(address), ll->n_conflict); + log_ipv4acd(acd, "Conflict on %s (%u)", strna(address), acd->n_conflict); - ipv4acd_reset(ll); - ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_CONFLICT); + ipv4acd_reset(acd); + ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_CONFLICT); } static int ipv4acd_on_packet( @@ -347,13 +347,13 @@ static int ipv4acd_on_packet( uint32_t revents, void *userdata) { - sd_ipv4acd *ll = userdata; + sd_ipv4acd *acd = userdata; struct ether_arp packet; ssize_t n; int r; assert(s); - assert(ll); + assert(acd); assert(fd >= 0); n = recv(fd, &packet, sizeof(struct ether_arp), 0); @@ -361,36 +361,36 @@ static int ipv4acd_on_packet( if (errno == EAGAIN || errno == EINTR) return 0; - log_ipv4acd_errno(ll, errno, "Failed to read ARP packet: %m"); + log_ipv4acd_errno(acd, errno, "Failed to read ARP packet: %m"); goto fail; } if ((size_t) n != sizeof(struct ether_arp)) { - log_ipv4acd(ll, "Ignoring too short ARP packet."); + log_ipv4acd(acd, "Ignoring too short ARP packet."); return 0; } - switch (ll->state) { + switch (acd->state) { case IPV4ACD_STATE_ANNOUNCING: case IPV4ACD_STATE_RUNNING: - if (ipv4acd_arp_conflict(ll, &packet)) { + if (ipv4acd_arp_conflict(acd, &packet)) { usec_t ts; - assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &ts) >= 0); + assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &ts) >= 0); /* Defend address */ - if (ts > ll->defend_window) { - ll->defend_window = ts + DEFEND_INTERVAL_USEC; - r = arp_send_announcement(ll->fd, ll->ifindex, ll->address, &ll->mac_addr); + if (ts > acd->defend_window) { + acd->defend_window = ts + DEFEND_INTERVAL_USEC; + r = arp_send_announcement(acd->fd, acd->ifindex, acd->address, &acd->mac_addr); if (r < 0) { - log_ipv4acd_errno(ll, r, "Failed to send ARP announcement: %m"); + log_ipv4acd_errno(acd, r, "Failed to send ARP announcement: %m"); goto fail; } else - log_ipv4acd(ll, "DEFEND"); + log_ipv4acd(acd, "DEFEND"); } else - ipv4acd_on_conflict(ll); + ipv4acd_on_conflict(acd); } break; @@ -398,7 +398,7 @@ static int ipv4acd_on_packet( case IPV4ACD_STATE_PROBING: case IPV4ACD_STATE_WAITING_ANNOUNCE: /* BPF ensures this packet indicates a conflict */ - ipv4acd_on_conflict(ll); + ipv4acd_on_conflict(acd); break; default: @@ -408,119 +408,119 @@ static int ipv4acd_on_packet( return 0; fail: - sd_ipv4acd_stop(ll); + sd_ipv4acd_stop(acd); return 0; } -int sd_ipv4acd_set_ifindex(sd_ipv4acd *ll, int ifindex) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int ifindex) { + assert_return(acd, -EINVAL); assert_return(ifindex > 0, -EINVAL); - assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); + assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY); - ll->ifindex = ifindex; + acd->ifindex = ifindex; return 0; } -int sd_ipv4acd_set_mac(sd_ipv4acd *ll, const struct ether_addr *addr) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr) { + assert_return(acd, -EINVAL); assert_return(addr, -EINVAL); - assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); + assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY); - ll->mac_addr = *addr; + acd->mac_addr = *addr; return 0; } -int sd_ipv4acd_detach_event(sd_ipv4acd *ll) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_detach_event(sd_ipv4acd *acd) { + assert_return(acd, -EINVAL); - ll->event = sd_event_unref(ll->event); + acd->event = sd_event_unref(acd->event); return 0; } -int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority) { +int sd_ipv4acd_attach_event(sd_ipv4acd *acd, sd_event *event, int64_t priority) { int r; - assert_return(ll, -EINVAL); - assert_return(!ll->event, -EBUSY); + assert_return(acd, -EINVAL); + assert_return(!acd->event, -EBUSY); if (event) - ll->event = sd_event_ref(event); + acd->event = sd_event_ref(event); else { - r = sd_event_default(&ll->event); + r = sd_event_default(&acd->event); if (r < 0) return r; } - ll->event_priority = priority; + acd->event_priority = priority; return 0; } -int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_set_callback(sd_ipv4acd *acd, sd_ipv4acd_callback_t cb, void *userdata) { + assert_return(acd, -EINVAL); - ll->callback = cb; - ll->userdata = userdata; + acd->callback = cb; + acd->userdata = userdata; return 0; } -int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address) { + assert_return(acd, -EINVAL); assert_return(address, -EINVAL); - assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); + assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY); - ll->address = address->s_addr; + acd->address = address->s_addr; return 0; } -int sd_ipv4acd_is_running(sd_ipv4acd *ll) { - assert_return(ll, false); +int sd_ipv4acd_is_running(sd_ipv4acd *acd) { + assert_return(acd, false); - return ll->state != IPV4ACD_STATE_INIT; + return acd->state != IPV4ACD_STATE_INIT; } -int sd_ipv4acd_start(sd_ipv4acd *ll) { +int sd_ipv4acd_start(sd_ipv4acd *acd) { int r; - assert_return(ll, -EINVAL); - assert_return(ll->event, -EINVAL); - assert_return(ll->ifindex > 0, -EINVAL); - assert_return(ll->address != 0, -EINVAL); - assert_return(!ether_addr_is_null(&ll->mac_addr), -EINVAL); - assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); + assert_return(acd, -EINVAL); + assert_return(acd->event, -EINVAL); + assert_return(acd->ifindex > 0, -EINVAL); + assert_return(acd->address != 0, -EINVAL); + assert_return(!ether_addr_is_null(&acd->mac_addr), -EINVAL); + assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY); - r = arp_network_bind_raw_socket(ll->ifindex, ll->address, &ll->mac_addr); + r = arp_network_bind_raw_socket(acd->ifindex, acd->address, &acd->mac_addr); if (r < 0) return r; - safe_close(ll->fd); - ll->fd = r; - ll->defend_window = 0; - ll->n_conflict = 0; + safe_close(acd->fd); + acd->fd = r; + acd->defend_window = 0; + acd->n_conflict = 0; - r = sd_event_add_io(ll->event, &ll->receive_message_event_source, ll->fd, EPOLLIN, ipv4acd_on_packet, ll); + r = sd_event_add_io(acd->event, &acd->receive_message_event_source, acd->fd, EPOLLIN, ipv4acd_on_packet, acd); if (r < 0) goto fail; - r = sd_event_source_set_priority(ll->receive_message_event_source, ll->event_priority); + r = sd_event_source_set_priority(acd->receive_message_event_source, acd->event_priority); if (r < 0) goto fail; - (void) sd_event_source_set_description(ll->receive_message_event_source, "ipv4acd-receive-message"); + (void) sd_event_source_set_description(acd->receive_message_event_source, "ipv4acd-receive-message"); - r = ipv4acd_set_next_wakeup(ll, 0, 0); + r = ipv4acd_set_next_wakeup(acd, 0, 0); if (r < 0) goto fail; - ipv4acd_set_state(ll, IPV4ACD_STATE_STARTED, true); + ipv4acd_set_state(acd, IPV4ACD_STATE_STARTED, true); return 0; fail: - ipv4acd_reset(ll); + ipv4acd_reset(acd); return r; } diff --git a/src/systemd/sd-ipv4acd.h b/src/systemd/sd-ipv4acd.h index 604160ae3f..16d99983a8 100644 --- a/src/systemd/sd-ipv4acd.h +++ b/src/systemd/sd-ipv4acd.h @@ -37,20 +37,20 @@ enum { }; typedef struct sd_ipv4acd sd_ipv4acd; -typedef void (*sd_ipv4acd_callback_t)(sd_ipv4acd *ll, int event, void *userdata); - -int sd_ipv4acd_detach_event(sd_ipv4acd *ll); -int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority); -int sd_ipv4acd_get_address(sd_ipv4acd *ll, struct in_addr *address); -int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata); -int sd_ipv4acd_set_mac(sd_ipv4acd *ll, const struct ether_addr *addr); -int sd_ipv4acd_set_ifindex(sd_ipv4acd *ll, int interface_index); -int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address); -int sd_ipv4acd_is_running(sd_ipv4acd *ll); -int sd_ipv4acd_start(sd_ipv4acd *ll); -int sd_ipv4acd_stop(sd_ipv4acd *ll); -sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *ll); -sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *ll); +typedef void (*sd_ipv4acd_callback_t)(sd_ipv4acd *acd, int event, void *userdata); + +int sd_ipv4acd_detach_event(sd_ipv4acd *acd); +int sd_ipv4acd_attach_event(sd_ipv4acd *acd, sd_event *event, int64_t priority); +int sd_ipv4acd_get_address(sd_ipv4acd *acd, struct in_addr *address); +int sd_ipv4acd_set_callback(sd_ipv4acd *acd, sd_ipv4acd_callback_t cb, void *userdata); +int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr); +int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int interface_index); +int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address); +int sd_ipv4acd_is_running(sd_ipv4acd *acd); +int sd_ipv4acd_start(sd_ipv4acd *acd); +int sd_ipv4acd_stop(sd_ipv4acd *acd); +sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd); +sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd); int sd_ipv4acd_new(sd_ipv4acd **ret); _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ipv4acd, sd_ipv4acd_unref); -- cgit v1.2.3-54-g00ecf From d54b734adc45708e34437f23878ce0601cfcc0ba Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 May 2016 21:15:49 +0200 Subject: sd-ndisc: Typo fix: s/advertisment/advertisement/ --- src/libsystemd-network/sd-ndisc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index c03e104e3b..c4d5eb45d2 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -40,7 +40,7 @@ enum NDiscState { NDISC_STATE_IDLE, NDISC_STATE_SOLICITATION_SENT, - NDISC_STATE_ADVERTISMENT_LISTEN, + NDISC_STATE_ADVERTISEMENT_LISTEN, _NDISC_STATE_MAX, _NDISC_STATE_INVALID = -1, }; @@ -355,7 +355,7 @@ static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, if (r != -EADDRNOTAVAIL) return r; - /* if router advertisment prefix valid timeout is zero, the timeout + /* if router advertisement prefix valid timeout is zero, the timeout callback will be called immediately to clean up the prefix */ r = ndisc_prefix_new(nd, &prefix); @@ -470,7 +470,7 @@ static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, ssize_t len return 0; } -static int ndisc_router_advertisment_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { +static int ndisc_router_advertisement_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { _cleanup_free_ struct nd_router_advert *ra = NULL; sd_ndisc *nd = userdata; union { @@ -565,7 +565,7 @@ static int ndisc_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r nd->timeout = sd_event_source_unref(nd->timeout); - nd->state = NDISC_STATE_ADVERTISMENT_LISTEN; + nd->state = NDISC_STATE_ADVERTISEMENT_LISTEN; stateful = ra->nd_ra_flags_reserved & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER); pref = (ra->nd_ra_flags_reserved & ND_RA_FLAG_PREF) >> 3; @@ -612,7 +612,7 @@ static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, if (nd->nd_sent >= NDISC_MAX_ROUTER_SOLICITATIONS) { if (nd->callback) nd->callback(nd, SD_NDISC_EVENT_TIMEOUT, nd->userdata); - nd->state = NDISC_STATE_ADVERTISMENT_LISTEN; + nd->state = NDISC_STATE_ADVERTISEMENT_LISTEN; } else { r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr); if (r < 0) @@ -680,7 +680,7 @@ int sd_ndisc_router_discovery_start(sd_ndisc *nd) { nd->fd = r; - r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN, ndisc_router_advertisment_recv, nd); + r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN, ndisc_router_advertisement_recv, nd); if (r < 0) goto fail; -- cgit v1.2.3-54-g00ecf From b3dfcf6a767442ca1e912615b49449d5095429fb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 May 2016 21:16:36 +0200 Subject: sd-ndisc: use the right object to pass to log_ndisc() There's no "client" object, in both cases. There's only "nd". This wasn't noticed before, as the context object is currently not actually used by the log macros. --- src/libsystemd-network/sd-ndisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index c4d5eb45d2..3432c71f33 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -655,7 +655,7 @@ int sd_ndisc_stop(sd_ndisc *nd) { if (nd->state == NDISC_STATE_IDLE) return 0; - log_ndisc(client, "Stopping IPv6 Router Solicitation client"); + log_ndisc(nd, "Stopping IPv6 Router Solicitation client"); ndisc_reset(nd); nd->state = NDISC_STATE_IDLE; @@ -700,7 +700,7 @@ int sd_ndisc_router_discovery_start(sd_ndisc *nd) { (void) sd_event_source_set_description(nd->timeout, "ndisc-timeout"); - log_ndisc(client, "Started IPv6 Router Solicitation client"); + log_ndisc(ns, "Started IPv6 Router Solicitation client"); return 0; fail: -- cgit v1.2.3-54-g00ecf From ad2998abd52678f49b2882a45474fd80fb90172c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 May 2016 21:20:30 +0200 Subject: sd-ndisc: add log_ndisc_errno() macro, to complement log_ndisc() like elsewhere Also make use of it where appropriate. --- src/libsystemd-network/sd-ndisc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 3432c71f33..2f021debc1 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -90,7 +90,8 @@ struct sd_ndisc { void *userdata; }; -#define log_ndisc(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "NDisc CLIENT: " fmt, ##__VA_ARGS__) +#define log_ndisc_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "NDisc CLIENT: " fmt, ##__VA_ARGS__) +#define log_ndisc(p, fmt, ...) log_ndisc_errno(p, 0, fmt, ##__VA_ARGS__) static NDiscPrefix *ndisc_prefix_unref(NDiscPrefix *prefix) { @@ -514,8 +515,7 @@ static int ndisc_router_advertisement_recv(sd_event_source *s, int fd, uint32_t if (errno == EAGAIN || errno == EINTR) return 0; - log_ndisc(nd, "Could not receive message from ICMPv6 socket: %m"); - return -errno; + return log_ndisc_errno(nd, errno, "Could not receive message from ICMPv6 socket: %m"); } if ((size_t) len < sizeof(struct nd_router_advert)) { log_ndisc(nd, "Too small to be a router advertisement: ignoring"); @@ -588,7 +588,7 @@ static int ndisc_router_advertisement_recv(sd_event_source *s, int fd, uint32_t r = ndisc_ra_parse(nd, ra, len); if (r < 0) { - log_ndisc(nd, "Could not parse Router Advertisement: %s", strerror(-r)); + log_ndisc_errno(nd, r, "Could not parse Router Advertisement: %m"); return 0; } @@ -616,7 +616,7 @@ static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, } else { r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr); if (r < 0) - log_ndisc(nd, "Error sending Router Solicitation"); + log_ndisc_errno(nd, r, "Error sending Router Solicitation: %m"); else { nd->state = NDISC_STATE_SOLICITATION_SENT; log_ndisc(nd, "Sent Router Solicitation"); -- cgit v1.2.3-54-g00ecf From 3e261cfd3ce480eb60014248368461548ef1601f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 May 2016 21:23:04 +0200 Subject: sd-ndisc: append "event_source" to event source objects stored in structures Otherwise it gets too confusing whether "timeout" refers to an event source or just a timeout time specification. --- src/libsystemd-network/sd-ndisc.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 2f021debc1..d1c51b4ed6 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -80,8 +80,8 @@ struct sd_ndisc { uint32_t mtu; LIST_HEAD(NDiscPrefix, prefixes); int fd; - sd_event_source *recv; - sd_event_source *timeout; + sd_event_source *recv_event_source; + sd_event_source *timeout_event_source; unsigned nd_sent; sd_ndisc_router_callback_t router_callback; sd_ndisc_prefix_autonomous_callback_t prefix_autonomous_callback; @@ -215,9 +215,9 @@ sd_ndisc *sd_ndisc_ref(sd_ndisc *nd) { static int ndisc_reset(sd_ndisc *nd) { assert(nd); - nd->recv = sd_event_source_unref(nd->recv); + nd->recv_event_source = sd_event_source_unref(nd->recv_event_source); nd->fd = asynchronous_close(nd->fd); - nd->timeout = sd_event_source_unref(nd->timeout); + nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); return 0; } @@ -563,7 +563,7 @@ static int ndisc_router_advertisement_recv(sd_event_source *s, int fd, uint32_t if (ra->nd_ra_code != 0) return 0; - nd->timeout = sd_event_source_unref(nd->timeout); + nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); nd->state = NDISC_STATE_ADVERTISEMENT_LISTEN; @@ -607,7 +607,7 @@ static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, assert(nd); assert(nd->event); - nd->timeout = sd_event_source_unref(nd->timeout); + nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); if (nd->nd_sent >= NDISC_MAX_ROUTER_SOLICITATIONS) { if (nd->callback) @@ -628,7 +628,7 @@ static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, next_timeout = time_now + NDISC_ROUTER_SOLICITATION_INTERVAL; - r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), + r = sd_event_add_time(nd->event, &nd->timeout_event_source, clock_boottime_or_monotonic(), next_timeout, 0, ndisc_router_solicitation_timeout, nd); if (r < 0) { @@ -637,13 +637,11 @@ static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, return 0; } - r = sd_event_source_set_priority(nd->timeout, nd->event_priority); + r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority); if (r < 0) return 0; - r = sd_event_source_set_description(nd->timeout, "ndisc-timeout"); - if (r < 0) - return 0; + (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout"); } return 0; @@ -680,25 +678,25 @@ int sd_ndisc_router_discovery_start(sd_ndisc *nd) { nd->fd = r; - r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN, ndisc_router_advertisement_recv, nd); + r = sd_event_add_io(nd->event, &nd->recv_event_source, nd->fd, EPOLLIN, ndisc_router_advertisement_recv, nd); if (r < 0) goto fail; - r = sd_event_source_set_priority(nd->recv, nd->event_priority); + r = sd_event_source_set_priority(nd->recv_event_source, nd->event_priority); if (r < 0) goto fail; - (void) sd_event_source_set_description(nd->recv, "ndisc-receive-message"); + (void) sd_event_source_set_description(nd->recv_event_source, "ndisc-receive-message"); - r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), 0, 0, ndisc_router_solicitation_timeout, nd); + r = sd_event_add_time(nd->event, &nd->timeout_event_source, clock_boottime_or_monotonic(), 0, 0, ndisc_router_solicitation_timeout, nd); if (r < 0) goto fail; - r = sd_event_source_set_priority(nd->timeout, nd->event_priority); + r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority); if (r < 0) goto fail; - (void) sd_event_source_set_description(nd->timeout, "ndisc-timeout"); + (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout"); log_ndisc(ns, "Started IPv6 Router Solicitation client"); return 0; -- cgit v1.2.3-54-g00ecf From 745c5152c210738e20bae5e377262e270f7a0335 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 May 2016 21:24:43 +0200 Subject: sd-ndisc: simplify clamping of router "pref" parameter --- src/libsystemd-network/sd-ndisc.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index d1c51b4ed6..c7969dbc1c 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -570,14 +570,8 @@ static int ndisc_router_advertisement_recv(sd_event_source *s, int fd, uint32_t stateful = ra->nd_ra_flags_reserved & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER); pref = (ra->nd_ra_flags_reserved & ND_RA_FLAG_PREF) >> 3; - switch (pref) { - case ND_RA_FLAG_PREF_LOW: - case ND_RA_FLAG_PREF_HIGH: - break; - default: + if (!IN_SET(pref, ND_RA_FLAG_PREF_LOW, ND_RA_FLAG_PREF_HIGH)) pref = ND_RA_FLAG_PREF_MEDIUM; - break; - } lifetime = be16toh(ra->nd_ra_router_lifetime); -- cgit v1.2.3-54-g00ecf From 901c983b6dca860e675fd77f703a44f15d900101 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 May 2016 21:28:11 +0200 Subject: sd-ndisc: rework size checking in ndisc_ra_parse() Let's better check the size before we subtract. Also, let's change the size argument to size_t, as it cannot be signed anyway. Finally, use EBADMSG for indicating invalid packets, like we do everywhere else. --- src/libsystemd-network/sd-ndisc.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index c7969dbc1c..36c6d444cc 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -336,7 +336,7 @@ static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, assert(prefix_opt); if (len < prefix_opt->nd_opt_pi_len) - return -ENOMSG; + return -EBADMSG; if (!(prefix_opt->nd_opt_pi_flags_reserved & (ND_OPT_PI_FLAG_ONLINK | ND_OPT_PI_FLAG_AUTO))) return 0; @@ -411,20 +411,19 @@ static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, return 0; } -static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, ssize_t len) { +static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, size_t len) { void *opt; struct nd_opt_hdr *opt_hdr; assert(nd); assert(ra); - len -= sizeof(*ra); - if (len < NDISC_OPT_LEN_UNITS) { + if (len < sizeof(struct nd_router_advert) + NDISC_OPT_LEN_UNITS) { log_ndisc(nd, "Router Advertisement below minimum length"); - - return -ENOMSG; + return -EBADMSG; } + len -= sizeof(struct nd_router_advert); opt = ra + 1; opt_hdr = opt; @@ -434,7 +433,7 @@ static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, ssize_t len struct nd_opt_prefix_info *opt_prefix; if (opt_hdr->nd_opt_len == 0) - return -ENOMSG; + return -EBADMSG; switch (opt_hdr->nd_opt_type) { case ND_OPT_MTU: @@ -580,7 +579,7 @@ static int ndisc_router_advertisement_recv(sd_event_source *s, int fd, uint32_t pref == ND_RA_FLAG_PREF_HIGH ? "high" : pref == ND_RA_FLAG_PREF_LOW ? "low" : "medium", lifetime); - r = ndisc_ra_parse(nd, ra, len); + r = ndisc_ra_parse(nd, ra, (size_t) len); if (r < 0) { log_ndisc_errno(nd, r, "Could not parse Router Advertisement: %m"); return 0; -- cgit v1.2.3-54-g00ecf From b9e7b1cf06cdfb95397b11c60211f5bbe9df28d1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 May 2016 21:32:33 +0200 Subject: sd-ndisc: stop discovery properly when something fails --- src/libsystemd-network/sd-ndisc.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 36c6d444cc..28133e7a69 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -608,9 +608,10 @@ static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, nd->state = NDISC_STATE_ADVERTISEMENT_LISTEN; } else { r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr); - if (r < 0) + if (r < 0) { log_ndisc_errno(nd, r, "Error sending Router Solicitation: %m"); - else { + goto fail; + } else { nd->state = NDISC_STATE_SOLICITATION_SENT; log_ndisc(nd, "Sent Router Solicitation"); } @@ -625,19 +626,24 @@ static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, next_timeout, 0, ndisc_router_solicitation_timeout, nd); if (r < 0) { - /* we cannot continue if we are unable to rearm the timer */ - sd_ndisc_stop(nd); - return 0; + log_ndisc_errno(nd, r, "Failed to allocate timer event: %m"); + goto fail; } r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority); - if (r < 0) - return 0; + if (r < 0) { + log_ndisc_errno(nd, r, "Cannot set timer priority: %m"); + goto fail; + } (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout"); } return 0; + +fail: + sd_ndisc_stop(nd); + return 0; } int sd_ndisc_stop(sd_ndisc *nd) { -- cgit v1.2.3-54-g00ecf From 79b490b79606519fc197bd65098208f9e1312e1b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 May 2016 21:34:25 +0200 Subject: sd-ndisc: add more whitespace Whitespace doesn't hurt and helps structuring things. --- src/libsystemd-network/sd-ndisc.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 28133e7a69..4744fec4c0 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -73,16 +73,22 @@ struct sd_ndisc { unsigned n_ref; enum NDiscState state; + int ifindex; + int fd; + sd_event *event; int event_priority; - int ifindex; + struct ether_addr mac_addr; uint32_t mtu; + LIST_HEAD(NDiscPrefix, prefixes); - int fd; + sd_event_source *recv_event_source; sd_event_source *timeout_event_source; + unsigned nd_sent; + sd_ndisc_router_callback_t router_callback; sd_ndisc_prefix_autonomous_callback_t prefix_autonomous_callback; sd_ndisc_prefix_onlink_callback_t prefix_onlink_callback; @@ -412,8 +418,8 @@ static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, } static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, size_t len) { - void *opt; struct nd_opt_hdr *opt_hdr; + void *opt; assert(nd); assert(ra); @@ -429,13 +435,14 @@ static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, size_t len) while (len != 0 && len >= opt_hdr->nd_opt_len * NDISC_OPT_LEN_UNITS) { struct nd_opt_mtu *opt_mtu; - uint32_t mtu; struct nd_opt_prefix_info *opt_prefix; + uint32_t mtu; if (opt_hdr->nd_opt_len == 0) return -EBADMSG; switch (opt_hdr->nd_opt_type) { + case ND_OPT_MTU: opt_mtu = opt; @@ -443,18 +450,14 @@ static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, size_t len) if (mtu != nd->mtu) { nd->mtu = MAX(mtu, IP6_MIN_MTU); - - log_ndisc(nd, "Router Advertisement link MTU %d using %d", - mtu, nd->mtu); + log_ndisc(nd, "Router Advertisement link MTU %d using %d", mtu, nd->mtu); } break; case ND_OPT_PREFIX_INFORMATION: opt_prefix = opt; - ndisc_prefix_update(nd, len, opt_prefix); - break; } @@ -563,7 +566,6 @@ static int ndisc_router_advertisement_recv(sd_event_source *s, int fd, uint32_t return 0; nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); - nd->state = NDISC_STATE_ADVERTISEMENT_LISTEN; stateful = ra->nd_ra_flags_reserved & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER); -- cgit v1.2.3-54-g00ecf From 9c4f6ccb70a192abb3ae58ac8f22d12c942ea898 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 May 2016 21:34:48 +0200 Subject: sd-ndisc: small coding style fixes Let's use usec_t internally always, when dealing with time values. Let's use uint8_t* pointers if we are dealing with generic byte pointers. --- src/libsystemd-network/sd-ndisc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 4744fec4c0..ccb8002173 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -462,8 +462,7 @@ static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, size_t len) } len -= opt_hdr->nd_opt_len * NDISC_OPT_LEN_UNITS; - opt = (void *)((char *)opt + - opt_hdr->nd_opt_len * NDISC_OPT_LEN_UNITS); + opt = (void*) ((uint8_t*) opt + opt_hdr->nd_opt_len * NDISC_OPT_LEN_UNITS); opt_hdr = opt; } @@ -595,7 +594,7 @@ static int ndisc_router_advertisement_recv(sd_event_source *s, int fd, uint32_t static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, void *userdata) { sd_ndisc *nd = userdata; - uint64_t time_now, next_timeout; + usec_t time_now, next_timeout; int r; assert(s); -- cgit v1.2.3-54-g00ecf From ae06d1be4efed2448315cd8e5e4bf08abaa03e26 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 May 2016 15:32:23 +0200 Subject: ipv4ll: shorten some checks by using IN_SET a bit As suggested: https://github.com/systemd/systemd/pull/3328#discussion-diff-64285764 --- src/libsystemd-network/sd-ipv4ll.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index cba9a89b76..5603a533a5 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -200,20 +200,12 @@ int sd_ipv4ll_is_running(sd_ipv4ll *ll) { } static bool ipv4ll_address_is_valid(const struct in_addr *address) { - uint32_t addr; - assert(address); if (!in_addr_is_link_local(AF_INET, (const union in_addr_union *) address)) return false; - addr = be32toh(address->s_addr); - - if ((addr & 0x0000FF00) == 0x0000 || - (addr & 0x0000FF00) == 0xFF00) - return false; - - return true; + return !IN_SET(be32toh(address->s_addr) & 0x0000FF00U, 0x0000U, 0xFF00U); } int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address) { @@ -250,8 +242,7 @@ static int ipv4ll_pick_address(sd_ipv4ll *ll) { addr = htobe32((h & UINT32_C(0x0000FFFF)) | IPV4LL_NETWORK); } while (addr == ll->address || - (be32toh(addr) & 0x0000FF00) == 0x0000 || - (be32toh(addr) & 0x0000FF00) == 0xFF00); + IN_SET(be32toh(addr) & 0x0000FF00U, 0x0000U, 0xFF00U)); (void) in_addr_to_string(AF_INET, &(union in_addr_union) { .in.s_addr = addr }, &address); log_ipv4ll(ll, "Picked new IP address %s.", strna(address)); -- cgit v1.2.3-54-g00ecf