From 3ad0c5d8a4e2e2fa7ffcccd7f3457f577908494e Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Thu, 15 Oct 2015 19:25:31 +0200 Subject: sd-icmp6-nd: rename files to sd-ndisc The actual code rename will follow. The reason for the change of name is to make it simpler and more uniform with how we name other libraries (we don't include the underlying protocol). The new name also matches the naming in the kernel (which is particularly relevent here as we expect to let the kernel do some parts of the protocol and we do others). --- src/libsystemd-network/network-internal.c | 2 +- src/libsystemd-network/sd-icmp6-nd.c | 720 ------------------------------ src/libsystemd-network/sd-ndisc.c | 720 ++++++++++++++++++++++++++++++ src/libsystemd-network/test-icmp6-rs.c | 357 --------------- src/libsystemd-network/test-ndisc-rs.c | 357 +++++++++++++++ src/network/networkd-dhcp6.c | 2 +- src/network/networkd-link.h | 2 +- src/systemd/sd-icmp6-nd.h | 79 ---- src/systemd/sd-ndisc.h | 79 ++++ 9 files changed, 1159 insertions(+), 1159 deletions(-) delete mode 100644 src/libsystemd-network/sd-icmp6-nd.c create mode 100644 src/libsystemd-network/sd-ndisc.c delete mode 100644 src/libsystemd-network/test-icmp6-rs.c create mode 100644 src/libsystemd-network/test-ndisc-rs.c delete mode 100644 src/systemd/sd-icmp6-nd.h create mode 100644 src/systemd/sd-ndisc.h (limited to 'src') diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index 2a62af2fd4..a33affb773 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -32,7 +32,7 @@ #include "conf-parser.h" #include "condition.h" #include "network-internal.h" -#include "sd-icmp6-nd.h" +#include "sd-ndisc.h" const char *net_get_name(struct udev_device *device) { const char *name, *field; diff --git a/src/libsystemd-network/sd-icmp6-nd.c b/src/libsystemd-network/sd-icmp6-nd.c deleted file mode 100644 index f014cac628..0000000000 --- a/src/libsystemd-network/sd-icmp6-nd.c +++ /dev/null @@ -1,720 +0,0 @@ -/*** - This file is part of systemd. - - Copyright (C) 2014 Intel Corporation. All rights reserved. - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include -#include -#include -#include -#include -#include - -#include "socket-util.h" -#include "async.h" - -#include "dhcp6-internal.h" -#include "sd-icmp6-nd.h" - -#define ICMP6_ROUTER_SOLICITATION_INTERVAL 4 * USEC_PER_SEC -#define ICMP6_MAX_ROUTER_SOLICITATIONS 3 - -enum icmp6_nd_state { - ICMP6_NEIGHBOR_DISCOVERY_IDLE = 0, - ICMP6_ROUTER_SOLICITATION_SENT = 10, - ICMP6_ROUTER_ADVERTISMENT_LISTEN = 11, -}; - -#define IP6_MIN_MTU (unsigned)1280 -#define ICMP6_ND_RECV_SIZE (IP6_MIN_MTU - sizeof(struct ip6_hdr)) -#define ICMP6_OPT_LEN_UNITS 8 - -typedef struct ICMP6Prefix ICMP6Prefix; - -struct ICMP6Prefix { - unsigned n_ref; - - LIST_FIELDS(ICMP6Prefix, prefixes); - - uint8_t len; - sd_event_source *timeout_valid; - struct in6_addr addr; -}; - -struct sd_icmp6_nd { - unsigned n_ref; - - enum icmp6_nd_state state; - sd_event *event; - int event_priority; - int index; - struct ether_addr mac_addr; - uint32_t mtu; - ICMP6Prefix *expired_prefix; - LIST_HEAD(ICMP6Prefix, prefixes); - int fd; - sd_event_source *recv; - sd_event_source *timeout; - int nd_sent; - sd_icmp6_nd_callback_t callback; - void *userdata; -}; - -#define log_icmp6_nd(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__) - -static ICMP6Prefix *icmp6_prefix_unref(ICMP6Prefix *prefix) { - - if (!prefix) - return NULL; - - assert(prefix->n_ref > 0); - prefix->n_ref--; - - if (prefix->n_ref > 0) - return NULL; - - prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid); - free(prefix); - return NULL; -} - -static int icmp6_prefix_new(ICMP6Prefix **ret) { - _cleanup_free_ ICMP6Prefix *prefix = NULL; - - assert(ret); - - prefix = new0(ICMP6Prefix, 1); - if (!prefix) - return -ENOMEM; - - prefix->n_ref = 1; - LIST_INIT(prefixes, prefix); - - *ret = prefix; - prefix = NULL; - - return 0; -} - -static void icmp6_nd_notify(sd_icmp6_nd *nd, int event) { - if (nd->callback) - nd->callback(nd, event, nd->userdata); -} - -int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t callback, - void *userdata) { - assert(nd); - - nd->callback = callback; - nd->userdata = userdata; - - return 0; -} - -int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index) { - assert(nd); - assert(interface_index >= -1); - - nd->index = interface_index; - - return 0; -} - -int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr) { - assert(nd); - - if (mac_addr) - memcpy(&nd->mac_addr, mac_addr, sizeof(nd->mac_addr)); - else - zero(nd->mac_addr); - - return 0; - -} - -int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority) { - int r; - - assert_return(nd, -EINVAL); - assert_return(!nd->event, -EBUSY); - - if (event) - nd->event = sd_event_ref(event); - else { - r = sd_event_default(&nd->event); - if (r < 0) - return 0; - } - - nd->event_priority = priority; - - return 0; -} - -int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd) { - assert_return(nd, -EINVAL); - - nd->event = sd_event_unref(nd->event); - - return 0; -} - -sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd) { - assert(nd); - - return nd->event; -} - -sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd) { - - if (!nd) - return NULL; - - assert(nd->n_ref > 0); - nd->n_ref++; - - return nd; -} - -static int icmp6_nd_init(sd_icmp6_nd *nd) { - assert(nd); - - nd->recv = sd_event_source_unref(nd->recv); - nd->fd = asynchronous_close(nd->fd); - nd->timeout = sd_event_source_unref(nd->timeout); - - return 0; -} - -sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) { - ICMP6Prefix *prefix, *p; - - if (!nd) - return NULL; - - assert(nd->n_ref > 0); - nd->n_ref--; - - if (nd->n_ref > 0) - return NULL; - - icmp6_nd_init(nd); - sd_icmp6_nd_detach_event(nd); - - LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { - LIST_REMOVE(prefixes, nd->prefixes, prefix); - - prefix = icmp6_prefix_unref(prefix); - } - - free(nd); - - return NULL; -} - -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_icmp6_nd*, sd_icmp6_nd_unref); -#define _cleanup_sd_icmp6_nd_free_ _cleanup_(sd_icmp6_nd_unrefp) - -int sd_icmp6_nd_new(sd_icmp6_nd **ret) { - _cleanup_sd_icmp6_nd_free_ sd_icmp6_nd *nd = NULL; - - assert(ret); - - nd = new0(sd_icmp6_nd, 1); - if (!nd) - return -ENOMEM; - - nd->n_ref = 1; - - nd->index = -1; - nd->fd = -1; - - LIST_HEAD_INIT(nd->prefixes); - - *ret = nd; - nd = NULL; - - return 0; -} - -int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu) { - assert_return(nd, -EINVAL); - assert_return(mtu, -EINVAL); - - if (nd->mtu == 0) - return -ENOMSG; - - *mtu = nd->mtu; - - return 0; -} - -static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec, - void *userdata) { - sd_icmp6_nd *nd = userdata; - ICMP6Prefix *prefix, *p; - - assert(nd); - - LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { - if (prefix->timeout_valid != s) - continue; - - log_icmp6_nd(nd, "Prefix expired "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d", - SD_ICMP6_ND_ADDRESS_FORMAT_VAL(prefix->addr), - prefix->len); - - LIST_REMOVE(prefixes, nd->prefixes, prefix); - - nd->expired_prefix = prefix; - icmp6_nd_notify(nd, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED); - nd->expired_prefix = NULL; - - prefix = icmp6_prefix_unref(prefix); - - break; - } - - return 0; -} - -static int icmp6_ra_prefix_set_timeout(sd_icmp6_nd *nd, - ICMP6Prefix *prefix, - usec_t valid) { - usec_t time_now; - int r; - - assert_return(prefix, -EINVAL); - - r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); - if (r < 0) - return r; - - prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid); - - r = sd_event_add_time(nd->event, &prefix->timeout_valid, - clock_boottime_or_monotonic(), time_now + valid, - USEC_PER_SEC, icmp6_ra_prefix_timeout, nd); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(prefix->timeout_valid, - nd->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(prefix->timeout_valid, - "icmp6-prefix-timeout"); - -error: - if (r < 0) - prefix->timeout_valid = - sd_event_source_unref(prefix->timeout_valid); - - return r; -} - -static int icmp6_prefix_match(const struct in6_addr *prefix, uint8_t prefixlen, - const struct in6_addr *addr, - uint8_t addr_prefixlen) { - uint8_t bytes, mask, len; - - assert_return(prefix, -EINVAL); - assert_return(addr, -EINVAL); - - len = MIN(prefixlen, addr_prefixlen); - - bytes = len / 8; - mask = 0xff << (8 - len % 8); - - if (memcmp(prefix, addr, bytes) != 0 || - (prefix->s6_addr[bytes] & mask) != (addr->s6_addr[bytes] & mask)) - return -EADDRNOTAVAIL; - - return 0; -} - -static int icmp6_ra_prefix_match(ICMP6Prefix *head, const struct in6_addr *addr, - uint8_t addr_len, ICMP6Prefix **result) { - ICMP6Prefix *prefix; - - LIST_FOREACH(prefixes, prefix, head) { - if (icmp6_prefix_match(&prefix->addr, prefix->len, addr, - addr_len) >= 0) { - *result = prefix; - return 0; - } - } - - return -EADDRNOTAVAIL; -} - -int sd_icmp6_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, - struct in6_addr *addr) { - return icmp6_prefix_match(prefix, prefixlen, addr, - sizeof(addr->s6_addr) * 8); -} - -int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr, - uint8_t *prefixlen) { - int r; - ICMP6Prefix *prefix; - - assert_return(nd, -EINVAL); - assert_return(addr, -EINVAL); - assert_return(prefixlen, -EINVAL); - - r = icmp6_ra_prefix_match(nd->prefixes, addr, - sizeof(addr->s6_addr) * 8, &prefix); - if (r < 0) - return r; - - *prefixlen = prefix->len; - - return 0; -} - -int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, uint8_t *prefixlen) { - assert_return(nd, -EINVAL); - assert_return(addr, -EINVAL); - assert_return(prefixlen, -EINVAL); - - if (!nd->expired_prefix) - return -EADDRNOTAVAIL; - - *addr = &nd->expired_prefix->addr; - *prefixlen = nd->expired_prefix->len; - - return 0; -} - -static int icmp6_ra_prefix_update(sd_icmp6_nd *nd, ssize_t len, - const struct nd_opt_prefix_info *prefix_opt) { - int r; - ICMP6Prefix *prefix; - uint32_t lifetime; - char time_string[FORMAT_TIMESPAN_MAX]; - - assert_return(nd, -EINVAL); - assert_return(prefix_opt, -EINVAL); - - if (len < prefix_opt->nd_opt_pi_len) - return -ENOMSG; - - if (!(prefix_opt->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK)) - return 0; - - lifetime = be32toh(prefix_opt->nd_opt_pi_valid_time); - - r = icmp6_ra_prefix_match(nd->prefixes, - &prefix_opt->nd_opt_pi_prefix, - prefix_opt->nd_opt_pi_prefix_len, &prefix); - - if (r < 0 && r != -EADDRNOTAVAIL) - return r; - - /* if router advertisment prefix valid timeout is zero, the timeout - callback will be called immediately to clean up the prefix */ - - if (r == -EADDRNOTAVAIL) { - r = icmp6_prefix_new(&prefix); - if (r < 0) - return r; - - prefix->len = prefix_opt->nd_opt_pi_prefix_len; - - memcpy(&prefix->addr, &prefix_opt->nd_opt_pi_prefix, - sizeof(prefix->addr)); - - log_icmp6_nd(nd, "New prefix "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", - SD_ICMP6_ND_ADDRESS_FORMAT_VAL(prefix->addr), - prefix->len, lifetime, - format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime * USEC_PER_SEC, USEC_PER_SEC)); - - LIST_PREPEND(prefixes, nd->prefixes, prefix); - - } else { - if (prefix->len != prefix_opt->nd_opt_pi_prefix_len) { - uint8_t prefixlen; - - prefixlen = MIN(prefix->len, prefix_opt->nd_opt_pi_prefix_len); - - log_icmp6_nd(nd, "Prefix length mismatch %d/%d using %d", - prefix->len, - prefix_opt->nd_opt_pi_prefix_len, - prefixlen); - - prefix->len = prefixlen; - } - - log_icmp6_nd(nd, "Update prefix "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", - SD_ICMP6_ND_ADDRESS_FORMAT_VAL(prefix->addr), - prefix->len, lifetime, - format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime * USEC_PER_SEC, USEC_PER_SEC)); - } - - r = icmp6_ra_prefix_set_timeout(nd, prefix, lifetime * USEC_PER_SEC); - - return r; -} - -static int icmp6_ra_parse(sd_icmp6_nd *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); - - len -= sizeof(*ra); - if (len < ICMP6_OPT_LEN_UNITS) { - log_icmp6_nd(nd, "Router Advertisement below minimum length"); - - return -ENOMSG; - } - - opt = ra + 1; - opt_hdr = opt; - - while (len != 0 && len >= opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS) { - struct nd_opt_mtu *opt_mtu; - uint32_t mtu; - struct nd_opt_prefix_info *opt_prefix; - - if (opt_hdr->nd_opt_len == 0) - return -ENOMSG; - - switch (opt_hdr->nd_opt_type) { - case ND_OPT_MTU: - opt_mtu = opt; - - mtu = be32toh(opt_mtu->nd_opt_mtu_mtu); - - if (mtu != nd->mtu) { - nd->mtu = MAX(mtu, IP6_MIN_MTU); - - log_icmp6_nd(nd, "Router Advertisement link MTU %d using %d", - mtu, nd->mtu); - } - - break; - - case ND_OPT_PREFIX_INFORMATION: - opt_prefix = opt; - - icmp6_ra_prefix_update(nd, len, opt_prefix); - - break; - } - - len -= opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS; - opt = (void *)((char *)opt + - opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS); - opt_hdr = opt; - } - - if (len > 0) - log_icmp6_nd(nd, "Router Advertisement contains %zd bytes of trailing garbage", len); - - return 0; -} - -static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - sd_icmp6_nd *nd = userdata; - int r, buflen = 0; - ssize_t len; - _cleanup_free_ struct nd_router_advert *ra = NULL; - int event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE; - - assert(s); - assert(nd); - assert(nd->event); - - r = ioctl(fd, FIONREAD, &buflen); - if (r < 0 || buflen <= 0) - buflen = ICMP6_ND_RECV_SIZE; - - ra = malloc(buflen); - if (!ra) - return -ENOMEM; - - len = read(fd, ra, buflen); - if (len < 0) { - log_icmp6_nd(nd, "Could not receive message from UDP socket: %m"); - return 0; - } - - if (ra->nd_ra_type != ND_ROUTER_ADVERT) - return 0; - - if (ra->nd_ra_code != 0) - return 0; - - nd->timeout = sd_event_source_unref(nd->timeout); - - nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; - - if (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER ) - event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER; - - if (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) - event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED; - - log_icmp6_nd(nd, "Received Router Advertisement flags %s/%s", - ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED? "MANAGED": "none", - ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER? "OTHER": "none"); - - if (event != SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE) { - r = icmp6_ra_parse(nd, ra, len); - if (r < 0) { - log_icmp6_nd(nd, "Could not parse Router Advertisement: %s", - strerror(-r)); - return 0; - } - } - - icmp6_nd_notify(nd, event); - - return 0; -} - -static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, void *userdata) { - sd_icmp6_nd *nd = userdata; - uint64_t time_now, next_timeout; - struct ether_addr unset = { }; - struct ether_addr *addr = NULL; - int r; - - assert(s); - assert(nd); - assert(nd->event); - - nd->timeout = sd_event_source_unref(nd->timeout); - - if (nd->nd_sent >= ICMP6_MAX_ROUTER_SOLICITATIONS) { - icmp6_nd_notify(nd, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT); - nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; - } else { - if (memcmp(&nd->mac_addr, &unset, sizeof(struct ether_addr))) - addr = &nd->mac_addr; - - r = dhcp_network_icmp6_send_router_solicitation(nd->fd, addr); - if (r < 0) - log_icmp6_nd(nd, "Error sending Router Solicitation"); - else { - nd->state = ICMP6_ROUTER_SOLICITATION_SENT; - log_icmp6_nd(nd, "Sent Router Solicitation"); - } - - nd->nd_sent++; - - r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); - if (r < 0) { - icmp6_nd_notify(nd, r); - return 0; - } - - next_timeout = time_now + ICMP6_ROUTER_SOLICITATION_INTERVAL; - - r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), - next_timeout, 0, - icmp6_router_solicitation_timeout, nd); - if (r < 0) { - icmp6_nd_notify(nd, r); - return 0; - } - - r = sd_event_source_set_priority(nd->timeout, - nd->event_priority); - if (r < 0) { - icmp6_nd_notify(nd, r); - return 0; - } - - r = sd_event_source_set_description(nd->timeout, "icmp6-timeout"); - if (r < 0) { - icmp6_nd_notify(nd, r); - return 0; - } - } - - return 0; -} - -int sd_icmp6_nd_stop(sd_icmp6_nd *nd) { - assert_return(nd, -EINVAL); - assert_return(nd->event, -EINVAL); - - log_icmp6_nd(client, "Stop ICMPv6"); - - icmp6_nd_init(nd); - - nd->state = ICMP6_NEIGHBOR_DISCOVERY_IDLE; - - return 0; -} - -int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd) { - int r; - - assert(nd); - assert(nd->event); - - if (nd->state != ICMP6_NEIGHBOR_DISCOVERY_IDLE) - return -EINVAL; - - if (nd->index < 1) - return -EINVAL; - - r = dhcp_network_icmp6_bind_router_solicitation(nd->index); - if (r < 0) - return r; - - nd->fd = r; - - r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN, - icmp6_router_advertisment_recv, nd); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(nd->recv, nd->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(nd->recv, "icmp6-receive-message"); - if (r < 0) - goto error; - - r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), - 0, 0, icmp6_router_solicitation_timeout, nd); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(nd->timeout, nd->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(nd->timeout, "icmp6-timeout"); -error: - if (r < 0) - icmp6_nd_init(nd); - else - log_icmp6_nd(client, "Start Router Solicitation"); - - return r; -} diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c new file mode 100644 index 0000000000..8545344fd7 --- /dev/null +++ b/src/libsystemd-network/sd-ndisc.c @@ -0,0 +1,720 @@ +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include "socket-util.h" +#include "async.h" + +#include "dhcp6-internal.h" +#include "sd-ndisc.h" + +#define ICMP6_ROUTER_SOLICITATION_INTERVAL 4 * USEC_PER_SEC +#define ICMP6_MAX_ROUTER_SOLICITATIONS 3 + +enum icmp6_nd_state { + ICMP6_NEIGHBOR_DISCOVERY_IDLE = 0, + ICMP6_ROUTER_SOLICITATION_SENT = 10, + ICMP6_ROUTER_ADVERTISMENT_LISTEN = 11, +}; + +#define IP6_MIN_MTU (unsigned)1280 +#define ICMP6_ND_RECV_SIZE (IP6_MIN_MTU - sizeof(struct ip6_hdr)) +#define ICMP6_OPT_LEN_UNITS 8 + +typedef struct ICMP6Prefix ICMP6Prefix; + +struct ICMP6Prefix { + unsigned n_ref; + + LIST_FIELDS(ICMP6Prefix, prefixes); + + uint8_t len; + sd_event_source *timeout_valid; + struct in6_addr addr; +}; + +struct sd_icmp6_nd { + unsigned n_ref; + + enum icmp6_nd_state state; + sd_event *event; + int event_priority; + int index; + struct ether_addr mac_addr; + uint32_t mtu; + ICMP6Prefix *expired_prefix; + LIST_HEAD(ICMP6Prefix, prefixes); + int fd; + sd_event_source *recv; + sd_event_source *timeout; + int nd_sent; + sd_icmp6_nd_callback_t callback; + void *userdata; +}; + +#define log_icmp6_nd(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__) + +static ICMP6Prefix *icmp6_prefix_unref(ICMP6Prefix *prefix) { + + if (!prefix) + return NULL; + + assert(prefix->n_ref > 0); + prefix->n_ref--; + + if (prefix->n_ref > 0) + return NULL; + + prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid); + free(prefix); + return NULL; +} + +static int icmp6_prefix_new(ICMP6Prefix **ret) { + _cleanup_free_ ICMP6Prefix *prefix = NULL; + + assert(ret); + + prefix = new0(ICMP6Prefix, 1); + if (!prefix) + return -ENOMEM; + + prefix->n_ref = 1; + LIST_INIT(prefixes, prefix); + + *ret = prefix; + prefix = NULL; + + return 0; +} + +static void icmp6_nd_notify(sd_icmp6_nd *nd, int event) { + if (nd->callback) + nd->callback(nd, event, nd->userdata); +} + +int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t callback, + void *userdata) { + assert(nd); + + nd->callback = callback; + nd->userdata = userdata; + + return 0; +} + +int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index) { + assert(nd); + assert(interface_index >= -1); + + nd->index = interface_index; + + return 0; +} + +int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr) { + assert(nd); + + if (mac_addr) + memcpy(&nd->mac_addr, mac_addr, sizeof(nd->mac_addr)); + else + zero(nd->mac_addr); + + return 0; + +} + +int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority) { + int r; + + assert_return(nd, -EINVAL); + assert_return(!nd->event, -EBUSY); + + if (event) + nd->event = sd_event_ref(event); + else { + r = sd_event_default(&nd->event); + if (r < 0) + return 0; + } + + nd->event_priority = priority; + + return 0; +} + +int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd) { + assert_return(nd, -EINVAL); + + nd->event = sd_event_unref(nd->event); + + return 0; +} + +sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd) { + assert(nd); + + return nd->event; +} + +sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd) { + + if (!nd) + return NULL; + + assert(nd->n_ref > 0); + nd->n_ref++; + + return nd; +} + +static int icmp6_nd_init(sd_icmp6_nd *nd) { + assert(nd); + + nd->recv = sd_event_source_unref(nd->recv); + nd->fd = asynchronous_close(nd->fd); + nd->timeout = sd_event_source_unref(nd->timeout); + + return 0; +} + +sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) { + ICMP6Prefix *prefix, *p; + + if (!nd) + return NULL; + + assert(nd->n_ref > 0); + nd->n_ref--; + + if (nd->n_ref > 0) + return NULL; + + icmp6_nd_init(nd); + sd_icmp6_nd_detach_event(nd); + + LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { + LIST_REMOVE(prefixes, nd->prefixes, prefix); + + prefix = icmp6_prefix_unref(prefix); + } + + free(nd); + + return NULL; +} + +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_icmp6_nd*, sd_icmp6_nd_unref); +#define _cleanup_sd_icmp6_nd_free_ _cleanup_(sd_icmp6_nd_unrefp) + +int sd_icmp6_nd_new(sd_icmp6_nd **ret) { + _cleanup_sd_icmp6_nd_free_ sd_icmp6_nd *nd = NULL; + + assert(ret); + + nd = new0(sd_icmp6_nd, 1); + if (!nd) + return -ENOMEM; + + nd->n_ref = 1; + + nd->index = -1; + nd->fd = -1; + + LIST_HEAD_INIT(nd->prefixes); + + *ret = nd; + nd = NULL; + + return 0; +} + +int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu) { + assert_return(nd, -EINVAL); + assert_return(mtu, -EINVAL); + + if (nd->mtu == 0) + return -ENOMSG; + + *mtu = nd->mtu; + + return 0; +} + +static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec, + void *userdata) { + sd_icmp6_nd *nd = userdata; + ICMP6Prefix *prefix, *p; + + assert(nd); + + LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { + if (prefix->timeout_valid != s) + continue; + + log_icmp6_nd(nd, "Prefix expired "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d", + SD_ICMP6_ND_ADDRESS_FORMAT_VAL(prefix->addr), + prefix->len); + + LIST_REMOVE(prefixes, nd->prefixes, prefix); + + nd->expired_prefix = prefix; + icmp6_nd_notify(nd, + SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED); + nd->expired_prefix = NULL; + + prefix = icmp6_prefix_unref(prefix); + + break; + } + + return 0; +} + +static int icmp6_ra_prefix_set_timeout(sd_icmp6_nd *nd, + ICMP6Prefix *prefix, + usec_t valid) { + usec_t time_now; + int r; + + assert_return(prefix, -EINVAL); + + r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) + return r; + + prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid); + + r = sd_event_add_time(nd->event, &prefix->timeout_valid, + clock_boottime_or_monotonic(), time_now + valid, + USEC_PER_SEC, icmp6_ra_prefix_timeout, nd); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(prefix->timeout_valid, + nd->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(prefix->timeout_valid, + "icmp6-prefix-timeout"); + +error: + if (r < 0) + prefix->timeout_valid = + sd_event_source_unref(prefix->timeout_valid); + + return r; +} + +static int icmp6_prefix_match(const struct in6_addr *prefix, uint8_t prefixlen, + const struct in6_addr *addr, + uint8_t addr_prefixlen) { + uint8_t bytes, mask, len; + + assert_return(prefix, -EINVAL); + assert_return(addr, -EINVAL); + + len = MIN(prefixlen, addr_prefixlen); + + bytes = len / 8; + mask = 0xff << (8 - len % 8); + + if (memcmp(prefix, addr, bytes) != 0 || + (prefix->s6_addr[bytes] & mask) != (addr->s6_addr[bytes] & mask)) + return -EADDRNOTAVAIL; + + return 0; +} + +static int icmp6_ra_prefix_match(ICMP6Prefix *head, const struct in6_addr *addr, + uint8_t addr_len, ICMP6Prefix **result) { + ICMP6Prefix *prefix; + + LIST_FOREACH(prefixes, prefix, head) { + if (icmp6_prefix_match(&prefix->addr, prefix->len, addr, + addr_len) >= 0) { + *result = prefix; + return 0; + } + } + + return -EADDRNOTAVAIL; +} + +int sd_icmp6_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, + struct in6_addr *addr) { + return icmp6_prefix_match(prefix, prefixlen, addr, + sizeof(addr->s6_addr) * 8); +} + +int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr, + uint8_t *prefixlen) { + int r; + ICMP6Prefix *prefix; + + assert_return(nd, -EINVAL); + assert_return(addr, -EINVAL); + assert_return(prefixlen, -EINVAL); + + r = icmp6_ra_prefix_match(nd->prefixes, addr, + sizeof(addr->s6_addr) * 8, &prefix); + if (r < 0) + return r; + + *prefixlen = prefix->len; + + return 0; +} + +int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, uint8_t *prefixlen) { + assert_return(nd, -EINVAL); + assert_return(addr, -EINVAL); + assert_return(prefixlen, -EINVAL); + + if (!nd->expired_prefix) + return -EADDRNOTAVAIL; + + *addr = &nd->expired_prefix->addr; + *prefixlen = nd->expired_prefix->len; + + return 0; +} + +static int icmp6_ra_prefix_update(sd_icmp6_nd *nd, ssize_t len, + const struct nd_opt_prefix_info *prefix_opt) { + int r; + ICMP6Prefix *prefix; + uint32_t lifetime; + char time_string[FORMAT_TIMESPAN_MAX]; + + assert_return(nd, -EINVAL); + assert_return(prefix_opt, -EINVAL); + + if (len < prefix_opt->nd_opt_pi_len) + return -ENOMSG; + + if (!(prefix_opt->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK)) + return 0; + + lifetime = be32toh(prefix_opt->nd_opt_pi_valid_time); + + r = icmp6_ra_prefix_match(nd->prefixes, + &prefix_opt->nd_opt_pi_prefix, + prefix_opt->nd_opt_pi_prefix_len, &prefix); + + if (r < 0 && r != -EADDRNOTAVAIL) + return r; + + /* if router advertisment prefix valid timeout is zero, the timeout + callback will be called immediately to clean up the prefix */ + + if (r == -EADDRNOTAVAIL) { + r = icmp6_prefix_new(&prefix); + if (r < 0) + return r; + + prefix->len = prefix_opt->nd_opt_pi_prefix_len; + + memcpy(&prefix->addr, &prefix_opt->nd_opt_pi_prefix, + sizeof(prefix->addr)); + + log_icmp6_nd(nd, "New prefix "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", + SD_ICMP6_ND_ADDRESS_FORMAT_VAL(prefix->addr), + prefix->len, lifetime, + format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime * USEC_PER_SEC, USEC_PER_SEC)); + + LIST_PREPEND(prefixes, nd->prefixes, prefix); + + } else { + if (prefix->len != prefix_opt->nd_opt_pi_prefix_len) { + uint8_t prefixlen; + + prefixlen = MIN(prefix->len, prefix_opt->nd_opt_pi_prefix_len); + + log_icmp6_nd(nd, "Prefix length mismatch %d/%d using %d", + prefix->len, + prefix_opt->nd_opt_pi_prefix_len, + prefixlen); + + prefix->len = prefixlen; + } + + log_icmp6_nd(nd, "Update prefix "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", + SD_ICMP6_ND_ADDRESS_FORMAT_VAL(prefix->addr), + prefix->len, lifetime, + format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime * USEC_PER_SEC, USEC_PER_SEC)); + } + + r = icmp6_ra_prefix_set_timeout(nd, prefix, lifetime * USEC_PER_SEC); + + return r; +} + +static int icmp6_ra_parse(sd_icmp6_nd *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); + + len -= sizeof(*ra); + if (len < ICMP6_OPT_LEN_UNITS) { + log_icmp6_nd(nd, "Router Advertisement below minimum length"); + + return -ENOMSG; + } + + opt = ra + 1; + opt_hdr = opt; + + while (len != 0 && len >= opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS) { + struct nd_opt_mtu *opt_mtu; + uint32_t mtu; + struct nd_opt_prefix_info *opt_prefix; + + if (opt_hdr->nd_opt_len == 0) + return -ENOMSG; + + switch (opt_hdr->nd_opt_type) { + case ND_OPT_MTU: + opt_mtu = opt; + + mtu = be32toh(opt_mtu->nd_opt_mtu_mtu); + + if (mtu != nd->mtu) { + nd->mtu = MAX(mtu, IP6_MIN_MTU); + + log_icmp6_nd(nd, "Router Advertisement link MTU %d using %d", + mtu, nd->mtu); + } + + break; + + case ND_OPT_PREFIX_INFORMATION: + opt_prefix = opt; + + icmp6_ra_prefix_update(nd, len, opt_prefix); + + break; + } + + len -= opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS; + opt = (void *)((char *)opt + + opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS); + opt_hdr = opt; + } + + if (len > 0) + log_icmp6_nd(nd, "Router Advertisement contains %zd bytes of trailing garbage", len); + + return 0; +} + +static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { + sd_icmp6_nd *nd = userdata; + int r, buflen = 0; + ssize_t len; + _cleanup_free_ struct nd_router_advert *ra = NULL; + int event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE; + + assert(s); + assert(nd); + assert(nd->event); + + r = ioctl(fd, FIONREAD, &buflen); + if (r < 0 || buflen <= 0) + buflen = ICMP6_ND_RECV_SIZE; + + ra = malloc(buflen); + if (!ra) + return -ENOMEM; + + len = read(fd, ra, buflen); + if (len < 0) { + log_icmp6_nd(nd, "Could not receive message from UDP socket: %m"); + return 0; + } + + if (ra->nd_ra_type != ND_ROUTER_ADVERT) + return 0; + + if (ra->nd_ra_code != 0) + return 0; + + nd->timeout = sd_event_source_unref(nd->timeout); + + nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; + + if (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER ) + event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER; + + if (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) + event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED; + + log_icmp6_nd(nd, "Received Router Advertisement flags %s/%s", + ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED? "MANAGED": "none", + ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER? "OTHER": "none"); + + if (event != SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE) { + r = icmp6_ra_parse(nd, ra, len); + if (r < 0) { + log_icmp6_nd(nd, "Could not parse Router Advertisement: %s", + strerror(-r)); + return 0; + } + } + + icmp6_nd_notify(nd, event); + + return 0; +} + +static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, void *userdata) { + sd_icmp6_nd *nd = userdata; + uint64_t time_now, next_timeout; + struct ether_addr unset = { }; + struct ether_addr *addr = NULL; + int r; + + assert(s); + assert(nd); + assert(nd->event); + + nd->timeout = sd_event_source_unref(nd->timeout); + + if (nd->nd_sent >= ICMP6_MAX_ROUTER_SOLICITATIONS) { + icmp6_nd_notify(nd, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT); + nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; + } else { + if (memcmp(&nd->mac_addr, &unset, sizeof(struct ether_addr))) + addr = &nd->mac_addr; + + r = dhcp_network_icmp6_send_router_solicitation(nd->fd, addr); + if (r < 0) + log_icmp6_nd(nd, "Error sending Router Solicitation"); + else { + nd->state = ICMP6_ROUTER_SOLICITATION_SENT; + log_icmp6_nd(nd, "Sent Router Solicitation"); + } + + nd->nd_sent++; + + r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) { + icmp6_nd_notify(nd, r); + return 0; + } + + next_timeout = time_now + ICMP6_ROUTER_SOLICITATION_INTERVAL; + + r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), + next_timeout, 0, + icmp6_router_solicitation_timeout, nd); + if (r < 0) { + icmp6_nd_notify(nd, r); + return 0; + } + + r = sd_event_source_set_priority(nd->timeout, + nd->event_priority); + if (r < 0) { + icmp6_nd_notify(nd, r); + return 0; + } + + r = sd_event_source_set_description(nd->timeout, "icmp6-timeout"); + if (r < 0) { + icmp6_nd_notify(nd, r); + return 0; + } + } + + return 0; +} + +int sd_icmp6_nd_stop(sd_icmp6_nd *nd) { + assert_return(nd, -EINVAL); + assert_return(nd->event, -EINVAL); + + log_icmp6_nd(client, "Stop ICMPv6"); + + icmp6_nd_init(nd); + + nd->state = ICMP6_NEIGHBOR_DISCOVERY_IDLE; + + return 0; +} + +int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd) { + int r; + + assert(nd); + assert(nd->event); + + if (nd->state != ICMP6_NEIGHBOR_DISCOVERY_IDLE) + return -EINVAL; + + if (nd->index < 1) + return -EINVAL; + + r = dhcp_network_icmp6_bind_router_solicitation(nd->index); + if (r < 0) + return r; + + nd->fd = r; + + r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN, + icmp6_router_advertisment_recv, nd); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(nd->recv, nd->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(nd->recv, "icmp6-receive-message"); + if (r < 0) + goto error; + + r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), + 0, 0, icmp6_router_solicitation_timeout, nd); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(nd->timeout, nd->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(nd->timeout, "icmp6-timeout"); +error: + if (r < 0) + icmp6_nd_init(nd); + else + log_icmp6_nd(client, "Start Router Solicitation"); + + return r; +} diff --git a/src/libsystemd-network/test-icmp6-rs.c b/src/libsystemd-network/test-icmp6-rs.c deleted file mode 100644 index 27b0ef4572..0000000000 --- a/src/libsystemd-network/test-icmp6-rs.c +++ /dev/null @@ -1,357 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright (C) 2014 Intel Corporation. All rights reserved. - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include - -#include "socket-util.h" - -#include "dhcp6-internal.h" -#include "sd-icmp6-nd.h" - -static struct ether_addr mac_addr = { - .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'} -}; - -static bool verbose = false; -static sd_event_source *test_hangcheck; -static int test_fd[2]; - -typedef int (*send_ra_t)(uint8_t flags); -static send_ra_t send_ra_function; - -static int test_rs_hangcheck(sd_event_source *s, uint64_t usec, - void *userdata) { - assert_se(false); - - return 0; -} - -int dhcp_network_icmp6_bind_router_solicitation(int index) { - assert_se(index == 42); - - if (socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) < 0) - return -errno; - - return test_fd[0]; -} - -static int send_ra_short_prefix(uint8_t flags) { - uint8_t advertisement[] = { - 0x86, 0x00, 0xbe, 0xd7, 0x40, 0xc0, 0x00, 0xb4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x03, 0x04, 0x34, 0xc0, 0x00, 0x00, 0x01, 0xf4, - 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == - sizeof(advertisement)); - - return 0; -} - -static void test_short_prefix_cb(sd_icmp6_nd *nd, int event, void *userdata) { - sd_event *e = userdata; - struct { - struct in6_addr addr; - uint8_t prefixlen; - bool success; - } addrs[] = { - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 52, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 64, false }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 60, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 64, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xed, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }, - 52, true }, - }; - uint8_t prefixlen; - unsigned int i; - - for (i = 0; i < ELEMENTSOF(addrs); i++) { - printf(" %s prefix %02x%02x:%02x%02x:%02x%02x:%02x%02x", - __FUNCTION__, - addrs[i].addr.s6_addr[0], addrs[i].addr.s6_addr[1], - addrs[i].addr.s6_addr[2], addrs[i].addr.s6_addr[3], - addrs[i].addr.s6_addr[4], addrs[i].addr.s6_addr[5], - addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]); - - if (addrs[i].success) { - assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, - &prefixlen) >= 0); - assert_se(addrs[i].prefixlen == prefixlen); - printf("/%d onlink\n", prefixlen); - } else { - assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, - &prefixlen) == -EADDRNOTAVAIL); - printf("/128 offlink\n"); - } - } - - sd_event_exit(e, 0); -} - -static int send_ra_prefixes(uint8_t flags) { - uint8_t advertisement[] = { - 0x86, 0x00, 0xbe, 0xd7, 0x40, 0xc0, 0x00, 0xb4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x3f, 0xc0, 0x00, 0x00, 0x01, 0xf4, - 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x40, 0x00, 0x00, 0x00, 0x02, 0x58, - 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x3c, 0x80, 0x00, 0x00, 0x03, 0x84, - 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x03, 0x84, - 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, - 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53 - }; - - assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == - sizeof(advertisement)); - - return 0; -} - -static void test_prefixes_cb(sd_icmp6_nd *nd, int event, void *userdata) { - sd_event *e = userdata; - struct { - struct in6_addr addr; - uint8_t prefixlen; - bool success; - } addrs[] = { - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 63, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 64, false }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 60, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 64, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xed, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }, - 63, false }, - }; - uint8_t prefixlen; - unsigned int i; - - for (i = 0; i < ELEMENTSOF(addrs); i++) { - printf(" %s prefix %02x%02x:%02x%02x:%02x%02x:%02x%02x", - __FUNCTION__, - addrs[i].addr.s6_addr[0], addrs[i].addr.s6_addr[1], - addrs[i].addr.s6_addr[2], addrs[i].addr.s6_addr[3], - addrs[i].addr.s6_addr[4], addrs[i].addr.s6_addr[5], - addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]); - - if (addrs[i].success) { - assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, - &prefixlen) >= 0); - assert_se(addrs[i].prefixlen == prefixlen); - printf("/%d onlink\n", prefixlen); - } else { - assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, - &prefixlen) == -EADDRNOTAVAIL); - printf("/128 offlink\n"); - } - } - - send_ra_function = send_ra_short_prefix; - assert_se(sd_icmp6_nd_set_callback(nd, test_short_prefix_cb, e) >= 0); - assert_se(sd_icmp6_nd_stop(nd) >= 0); - assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); -} - -static void test_prefixes(void) { - sd_event *e; - sd_icmp6_nd *nd; - - if (verbose) - printf("* %s\n", __FUNCTION__); - - send_ra_function = send_ra_prefixes; - - assert_se(sd_event_new(&e) >= 0); - - assert_se(sd_icmp6_nd_new(&nd) >= 0); - assert_se(nd); - - assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0); - - assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0); - assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0); - assert_se(sd_icmp6_nd_set_callback(nd, test_prefixes_cb, e) >= 0); - - assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); - - sd_event_loop(e); - - nd = sd_icmp6_nd_unref(nd); - assert_se(!nd); - - close(test_fd[1]); - - sd_event_unref(e); -} - -static int send_ra(uint8_t flags) { - uint8_t advertisement[] = { - 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4, - 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, - 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, - }; - - advertisement[5] = flags; - - assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == - sizeof(advertisement)); - - if (verbose) - printf(" sent RA with flag 0x%02x\n", flags); - - return 0; -} - -int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) { - return send_ra_function(0); -} - -static void test_rs_done(sd_icmp6_nd *nd, int event, void *userdata) { - sd_event *e = userdata; - static int idx = 0; - struct { - uint8_t flag; - int event; - } flag_event[] = { - { 0, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE }, - { ND_RA_FLAG_OTHER, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER }, - { ND_RA_FLAG_MANAGED, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED } - }; - uint32_t mtu; - - assert_se(nd); - - assert_se(event == flag_event[idx].event); - idx++; - - if (verbose) - printf(" got event %d\n", event); - - if (idx < 3) { - send_ra(flag_event[idx].flag); - return; - } - - assert_se(sd_icmp6_ra_get_mtu(nd, &mtu) == -ENOMSG); - - sd_event_exit(e, 0); -} - -static void test_rs(void) { - sd_event *e; - sd_icmp6_nd *nd; - usec_t time_now = now(clock_boottime_or_monotonic()); - - if (verbose) - printf("* %s\n", __FUNCTION__); - - send_ra_function = send_ra; - - assert_se(sd_event_new(&e) >= 0); - - assert_se(sd_icmp6_nd_new(&nd) >= 0); - assert_se(nd); - - assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0); - - assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0); - assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0); - assert_se(sd_icmp6_nd_set_callback(nd, test_rs_done, e) >= 0); - - assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(), - time_now + 2 *USEC_PER_SEC, 0, - test_rs_hangcheck, NULL) >= 0); - - assert_se(sd_icmp6_nd_stop(nd) >= 0); - assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); - assert_se(sd_icmp6_nd_stop(nd) >= 0); - - assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); - - sd_event_loop(e); - - test_hangcheck = sd_event_source_unref(test_hangcheck); - - nd = sd_icmp6_nd_unref(nd); - assert_se(!nd); - - close(test_fd[1]); - - sd_event_unref(e); -} - -int main(int argc, char *argv[]) { - - log_set_max_level(LOG_DEBUG); - log_parse_environment(); - log_open(); - - test_rs(); - test_prefixes(); - - return 0; -} diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c new file mode 100644 index 0000000000..49305e297b --- /dev/null +++ b/src/libsystemd-network/test-ndisc-rs.c @@ -0,0 +1,357 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "socket-util.h" + +#include "dhcp6-internal.h" +#include "sd-ndisc.h" + +static struct ether_addr mac_addr = { + .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'} +}; + +static bool verbose = false; +static sd_event_source *test_hangcheck; +static int test_fd[2]; + +typedef int (*send_ra_t)(uint8_t flags); +static send_ra_t send_ra_function; + +static int test_rs_hangcheck(sd_event_source *s, uint64_t usec, + void *userdata) { + assert_se(false); + + return 0; +} + +int dhcp_network_icmp6_bind_router_solicitation(int index) { + assert_se(index == 42); + + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) < 0) + return -errno; + + return test_fd[0]; +} + +static int send_ra_short_prefix(uint8_t flags) { + uint8_t advertisement[] = { + 0x86, 0x00, 0xbe, 0xd7, 0x40, 0xc0, 0x00, 0xb4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x03, 0x04, 0x34, 0xc0, 0x00, 0x00, 0x01, 0xf4, + 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == + sizeof(advertisement)); + + return 0; +} + +static void test_short_prefix_cb(sd_icmp6_nd *nd, int event, void *userdata) { + sd_event *e = userdata; + struct { + struct in6_addr addr; + uint8_t prefixlen; + bool success; + } addrs[] = { + { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 52, true }, + { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 64, false }, + { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 60, true }, + { { { { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 64, true }, + { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xed, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }, + 52, true }, + }; + uint8_t prefixlen; + unsigned int i; + + for (i = 0; i < ELEMENTSOF(addrs); i++) { + printf(" %s prefix %02x%02x:%02x%02x:%02x%02x:%02x%02x", + __FUNCTION__, + addrs[i].addr.s6_addr[0], addrs[i].addr.s6_addr[1], + addrs[i].addr.s6_addr[2], addrs[i].addr.s6_addr[3], + addrs[i].addr.s6_addr[4], addrs[i].addr.s6_addr[5], + addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]); + + if (addrs[i].success) { + assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, + &prefixlen) >= 0); + assert_se(addrs[i].prefixlen == prefixlen); + printf("/%d onlink\n", prefixlen); + } else { + assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, + &prefixlen) == -EADDRNOTAVAIL); + printf("/128 offlink\n"); + } + } + + sd_event_exit(e, 0); +} + +static int send_ra_prefixes(uint8_t flags) { + uint8_t advertisement[] = { + 0x86, 0x00, 0xbe, 0xd7, 0x40, 0xc0, 0x00, 0xb4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x04, 0x3f, 0xc0, 0x00, 0x00, 0x01, 0xf4, + 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x04, 0x40, 0x00, 0x00, 0x00, 0x02, 0x58, + 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x04, 0x3c, 0x80, 0x00, 0x00, 0x03, 0x84, + 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x03, 0x84, + 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, + 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, + 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, + 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53 + }; + + assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == + sizeof(advertisement)); + + return 0; +} + +static void test_prefixes_cb(sd_icmp6_nd *nd, int event, void *userdata) { + sd_event *e = userdata; + struct { + struct in6_addr addr; + uint8_t prefixlen; + bool success; + } addrs[] = { + { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 63, true }, + { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 64, false }, + { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 60, true }, + { { { { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 64, true }, + { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xed, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }, + 63, false }, + }; + uint8_t prefixlen; + unsigned int i; + + for (i = 0; i < ELEMENTSOF(addrs); i++) { + printf(" %s prefix %02x%02x:%02x%02x:%02x%02x:%02x%02x", + __FUNCTION__, + addrs[i].addr.s6_addr[0], addrs[i].addr.s6_addr[1], + addrs[i].addr.s6_addr[2], addrs[i].addr.s6_addr[3], + addrs[i].addr.s6_addr[4], addrs[i].addr.s6_addr[5], + addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]); + + if (addrs[i].success) { + assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, + &prefixlen) >= 0); + assert_se(addrs[i].prefixlen == prefixlen); + printf("/%d onlink\n", prefixlen); + } else { + assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, + &prefixlen) == -EADDRNOTAVAIL); + printf("/128 offlink\n"); + } + } + + send_ra_function = send_ra_short_prefix; + assert_se(sd_icmp6_nd_set_callback(nd, test_short_prefix_cb, e) >= 0); + assert_se(sd_icmp6_nd_stop(nd) >= 0); + assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); +} + +static void test_prefixes(void) { + sd_event *e; + sd_icmp6_nd *nd; + + if (verbose) + printf("* %s\n", __FUNCTION__); + + send_ra_function = send_ra_prefixes; + + assert_se(sd_event_new(&e) >= 0); + + assert_se(sd_icmp6_nd_new(&nd) >= 0); + assert_se(nd); + + assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0); + + assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0); + assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0); + assert_se(sd_icmp6_nd_set_callback(nd, test_prefixes_cb, e) >= 0); + + assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); + + sd_event_loop(e); + + nd = sd_icmp6_nd_unref(nd); + assert_se(!nd); + + close(test_fd[1]); + + sd_event_unref(e); +} + +static int send_ra(uint8_t flags) { + uint8_t advertisement[] = { + 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4, + 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, + 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, + 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, + 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, + }; + + advertisement[5] = flags; + + assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == + sizeof(advertisement)); + + if (verbose) + printf(" sent RA with flag 0x%02x\n", flags); + + return 0; +} + +int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) { + return send_ra_function(0); +} + +static void test_rs_done(sd_icmp6_nd *nd, int event, void *userdata) { + sd_event *e = userdata; + static int idx = 0; + struct { + uint8_t flag; + int event; + } flag_event[] = { + { 0, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE }, + { ND_RA_FLAG_OTHER, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER }, + { ND_RA_FLAG_MANAGED, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED } + }; + uint32_t mtu; + + assert_se(nd); + + assert_se(event == flag_event[idx].event); + idx++; + + if (verbose) + printf(" got event %d\n", event); + + if (idx < 3) { + send_ra(flag_event[idx].flag); + return; + } + + assert_se(sd_icmp6_ra_get_mtu(nd, &mtu) == -ENOMSG); + + sd_event_exit(e, 0); +} + +static void test_rs(void) { + sd_event *e; + sd_icmp6_nd *nd; + usec_t time_now = now(clock_boottime_or_monotonic()); + + if (verbose) + printf("* %s\n", __FUNCTION__); + + send_ra_function = send_ra; + + assert_se(sd_event_new(&e) >= 0); + + assert_se(sd_icmp6_nd_new(&nd) >= 0); + assert_se(nd); + + assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0); + + assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0); + assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0); + assert_se(sd_icmp6_nd_set_callback(nd, test_rs_done, e) >= 0); + + assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(), + time_now + 2 *USEC_PER_SEC, 0, + test_rs_hangcheck, NULL) >= 0); + + assert_se(sd_icmp6_nd_stop(nd) >= 0); + assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); + assert_se(sd_icmp6_nd_stop(nd) >= 0); + + assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); + + sd_event_loop(e); + + test_hangcheck = sd_event_source_unref(test_hangcheck); + + nd = sd_icmp6_nd_unref(nd); + assert_se(!nd); + + close(test_fd[1]); + + sd_event_unref(e); +} + +int main(int argc, char *argv[]) { + + log_set_max_level(LOG_DEBUG); + log_parse_environment(); + log_open(); + + test_rs(); + test_prefixes(); + + return 0; +} diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index fb93e6606e..e572ad4595 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -25,7 +25,7 @@ #include "networkd-link.h" #include "network-internal.h" -#include "sd-icmp6-nd.h" +#include "sd-ndisc.h" #include "sd-dhcp6-client.h" static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link); diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index af2ba11701..5bba313049 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -26,7 +26,7 @@ #include "sd-dhcp-client.h" #include "sd-dhcp-server.h" #include "sd-ipv4ll.h" -#include "sd-icmp6-nd.h" +#include "sd-ndisc.h" #include "sd-dhcp6-client.h" #include "sd-lldp.h" diff --git a/src/systemd/sd-icmp6-nd.h b/src/systemd/sd-icmp6-nd.h deleted file mode 100644 index cb6c24a0cb..0000000000 --- a/src/systemd/sd-icmp6-nd.h +++ /dev/null @@ -1,79 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#ifndef foosdicmp6ndfoo -#define foosdicmp6ndfoo - -/*** - This file is part of systemd. - - Copyright (C) 2014 Intel Corporation. All rights reserved. - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include - -#include "sd-event.h" - -enum { - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE = 0, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT = 1, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER = 2, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED = 3, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED = 4, -}; - -typedef struct sd_icmp6_nd sd_icmp6_nd; - -typedef void(*sd_icmp6_nd_callback_t)(sd_icmp6_nd *nd, int event, - void *userdata); - -int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t cb, - void *userdata); -int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index); -int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr); - -int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority); -int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd); -sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd); - -sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd); -sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd); -int sd_icmp6_nd_new(sd_icmp6_nd **ret); - -int sd_icmp6_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, - struct in6_addr *addr); - -int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu); -int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr, - uint8_t *prefixlen); -int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, - uint8_t *prefixlen); - -int sd_icmp6_nd_stop(sd_icmp6_nd *nd); -int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd); - -#define SD_ICMP6_ND_ADDRESS_FORMAT_STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" - -#define SD_ICMP6_ND_ADDRESS_FORMAT_VAL(address) \ - be16toh((address).s6_addr16[0]), \ - be16toh((address).s6_addr16[1]), \ - be16toh((address).s6_addr16[2]), \ - be16toh((address).s6_addr16[3]), \ - be16toh((address).s6_addr16[4]), \ - be16toh((address).s6_addr16[5]), \ - be16toh((address).s6_addr16[6]), \ - be16toh((address).s6_addr16[7]) - -#endif diff --git a/src/systemd/sd-ndisc.h b/src/systemd/sd-ndisc.h new file mode 100644 index 0000000000..240feb7bbe --- /dev/null +++ b/src/systemd/sd-ndisc.h @@ -0,0 +1,79 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdndiscfoo +#define foosdndiscfoo + +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "sd-event.h" + +enum { + SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE = 0, + SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT = 1, + SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER = 2, + SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED = 3, + SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED = 4, +}; + +typedef struct sd_icmp6_nd sd_icmp6_nd; + +typedef void(*sd_icmp6_nd_callback_t)(sd_icmp6_nd *nd, int event, + void *userdata); + +int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t cb, + void *userdata); +int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index); +int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr); + +int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority); +int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd); +sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd); + +sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd); +sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd); +int sd_icmp6_nd_new(sd_icmp6_nd **ret); + +int sd_icmp6_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, + struct in6_addr *addr); + +int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu); +int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr, + uint8_t *prefixlen); +int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, + uint8_t *prefixlen); + +int sd_icmp6_nd_stop(sd_icmp6_nd *nd); +int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd); + +#define SD_ICMP6_ND_ADDRESS_FORMAT_STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" + +#define SD_ICMP6_ND_ADDRESS_FORMAT_VAL(address) \ + be16toh((address).s6_addr16[0]), \ + be16toh((address).s6_addr16[1]), \ + be16toh((address).s6_addr16[2]), \ + be16toh((address).s6_addr16[3]), \ + be16toh((address).s6_addr16[4]), \ + be16toh((address).s6_addr16[5]), \ + be16toh((address).s6_addr16[6]), \ + be16toh((address).s6_addr16[7]) + +#endif -- cgit v1.2.3-54-g00ecf From 4d7b83da7b78647f4ba3f1d6fa2dc8d7b9833d93 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 16 Oct 2015 17:07:47 +0200 Subject: sd-ndisc: rename API from sd-icmp6-nd --- src/libsystemd-network/network-internal.c | 4 +- src/libsystemd-network/sd-ndisc.c | 84 +++++++++++++++---------------- src/libsystemd-network/test-ndisc-rs.c | 66 ++++++++++++------------ src/network/networkd-dhcp6.c | 48 +++++++++--------- src/network/networkd-link.c | 6 +-- src/network/networkd-link.h | 2 +- src/systemd/sd-ndisc.h | 48 +++++++++--------- 7 files changed, 129 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index a33affb773..faf14fe6a2 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -390,8 +390,8 @@ void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses, assert(size); for (i = 0; i < size; i++) - fprintf(f, SD_ICMP6_ND_ADDRESS_FORMAT_STR"%s", - SD_ICMP6_ND_ADDRESS_FORMAT_VAL(addresses[i]), + fprintf(f, SD_NDISC_ADDRESS_FORMAT_STR"%s", + SD_NDISC_ADDRESS_FORMAT_VAL(addresses[i]), (i < (size - 1)) ? " ": ""); } diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 8545344fd7..eb6529287f 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -55,7 +55,7 @@ struct ICMP6Prefix { struct in6_addr addr; }; -struct sd_icmp6_nd { +struct sd_ndisc { unsigned n_ref; enum icmp6_nd_state state; @@ -70,7 +70,7 @@ struct sd_icmp6_nd { sd_event_source *recv; sd_event_source *timeout; int nd_sent; - sd_icmp6_nd_callback_t callback; + sd_ndisc_callback_t callback; void *userdata; }; @@ -110,12 +110,12 @@ static int icmp6_prefix_new(ICMP6Prefix **ret) { return 0; } -static void icmp6_nd_notify(sd_icmp6_nd *nd, int event) { +static void icmp6_nd_notify(sd_ndisc *nd, int event) { if (nd->callback) nd->callback(nd, event, nd->userdata); } -int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t callback, +int sd_ndisc_set_callback(sd_ndisc *nd, sd_ndisc_callback_t callback, void *userdata) { assert(nd); @@ -125,7 +125,7 @@ int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t callback, return 0; } -int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index) { +int sd_ndisc_set_index(sd_ndisc *nd, int interface_index) { assert(nd); assert(interface_index >= -1); @@ -134,7 +134,7 @@ int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index) { return 0; } -int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr) { +int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr) { assert(nd); if (mac_addr) @@ -146,7 +146,7 @@ int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr) { } -int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority) { +int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int priority) { int r; assert_return(nd, -EINVAL); @@ -165,7 +165,7 @@ int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority) { return 0; } -int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd) { +int sd_ndisc_detach_event(sd_ndisc *nd) { assert_return(nd, -EINVAL); nd->event = sd_event_unref(nd->event); @@ -173,13 +173,13 @@ int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd) { return 0; } -sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd) { +sd_event *sd_ndisc_get_event(sd_ndisc *nd) { assert(nd); return nd->event; } -sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd) { +sd_ndisc *sd_ndisc_ref(sd_ndisc *nd) { if (!nd) return NULL; @@ -190,7 +190,7 @@ sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd) { return nd; } -static int icmp6_nd_init(sd_icmp6_nd *nd) { +static int icmp6_nd_init(sd_ndisc *nd) { assert(nd); nd->recv = sd_event_source_unref(nd->recv); @@ -200,7 +200,7 @@ static int icmp6_nd_init(sd_icmp6_nd *nd) { return 0; } -sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) { +sd_ndisc *sd_ndisc_unref(sd_ndisc *nd) { ICMP6Prefix *prefix, *p; if (!nd) @@ -213,7 +213,7 @@ sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) { return NULL; icmp6_nd_init(nd); - sd_icmp6_nd_detach_event(nd); + sd_ndisc_detach_event(nd); LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { LIST_REMOVE(prefixes, nd->prefixes, prefix); @@ -226,15 +226,15 @@ sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) { return NULL; } -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_icmp6_nd*, sd_icmp6_nd_unref); -#define _cleanup_sd_icmp6_nd_free_ _cleanup_(sd_icmp6_nd_unrefp) +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_ndisc*, sd_ndisc_unref); +#define _cleanup_sd_ndisc_free_ _cleanup_(sd_ndisc_unrefp) -int sd_icmp6_nd_new(sd_icmp6_nd **ret) { - _cleanup_sd_icmp6_nd_free_ sd_icmp6_nd *nd = NULL; +int sd_ndisc_new(sd_ndisc **ret) { + _cleanup_sd_ndisc_free_ sd_ndisc *nd = NULL; assert(ret); - nd = new0(sd_icmp6_nd, 1); + nd = new0(sd_ndisc, 1); if (!nd) return -ENOMEM; @@ -251,7 +251,7 @@ int sd_icmp6_nd_new(sd_icmp6_nd **ret) { return 0; } -int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu) { +int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu) { assert_return(nd, -EINVAL); assert_return(mtu, -EINVAL); @@ -265,7 +265,7 @@ int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu) { static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec, void *userdata) { - sd_icmp6_nd *nd = userdata; + sd_ndisc *nd = userdata; ICMP6Prefix *prefix, *p; assert(nd); @@ -274,15 +274,15 @@ static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec, if (prefix->timeout_valid != s) continue; - log_icmp6_nd(nd, "Prefix expired "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d", - SD_ICMP6_ND_ADDRESS_FORMAT_VAL(prefix->addr), + log_icmp6_nd(nd, "Prefix expired "SD_NDISC_ADDRESS_FORMAT_STR"/%d", + SD_NDISC_ADDRESS_FORMAT_VAL(prefix->addr), prefix->len); LIST_REMOVE(prefixes, nd->prefixes, prefix); nd->expired_prefix = prefix; icmp6_nd_notify(nd, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED); + SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED); nd->expired_prefix = NULL; prefix = icmp6_prefix_unref(prefix); @@ -293,7 +293,7 @@ static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec, return 0; } -static int icmp6_ra_prefix_set_timeout(sd_icmp6_nd *nd, +static int icmp6_ra_prefix_set_timeout(sd_ndisc *nd, ICMP6Prefix *prefix, usec_t valid) { usec_t time_now; @@ -364,13 +364,13 @@ static int icmp6_ra_prefix_match(ICMP6Prefix *head, const struct in6_addr *addr, return -EADDRNOTAVAIL; } -int sd_icmp6_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, +int sd_ndisc_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, struct in6_addr *addr) { return icmp6_prefix_match(prefix, prefixlen, addr, sizeof(addr->s6_addr) * 8); } -int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr, +int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, uint8_t *prefixlen) { int r; ICMP6Prefix *prefix; @@ -389,7 +389,7 @@ int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr, return 0; } -int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, uint8_t *prefixlen) { +int sd_ndisc_get_expired_prefix(sd_ndisc *nd, struct in6_addr **addr, uint8_t *prefixlen) { assert_return(nd, -EINVAL); assert_return(addr, -EINVAL); assert_return(prefixlen, -EINVAL); @@ -403,7 +403,7 @@ int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, uint return 0; } -static int icmp6_ra_prefix_update(sd_icmp6_nd *nd, ssize_t len, +static int icmp6_ra_prefix_update(sd_ndisc *nd, ssize_t len, const struct nd_opt_prefix_info *prefix_opt) { int r; ICMP6Prefix *prefix; @@ -441,8 +441,8 @@ static int icmp6_ra_prefix_update(sd_icmp6_nd *nd, ssize_t len, memcpy(&prefix->addr, &prefix_opt->nd_opt_pi_prefix, sizeof(prefix->addr)); - log_icmp6_nd(nd, "New prefix "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", - SD_ICMP6_ND_ADDRESS_FORMAT_VAL(prefix->addr), + log_icmp6_nd(nd, "New prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", + SD_NDISC_ADDRESS_FORMAT_VAL(prefix->addr), prefix->len, lifetime, format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime * USEC_PER_SEC, USEC_PER_SEC)); @@ -462,8 +462,8 @@ static int icmp6_ra_prefix_update(sd_icmp6_nd *nd, ssize_t len, prefix->len = prefixlen; } - log_icmp6_nd(nd, "Update prefix "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", - SD_ICMP6_ND_ADDRESS_FORMAT_VAL(prefix->addr), + log_icmp6_nd(nd, "Update prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", + SD_NDISC_ADDRESS_FORMAT_VAL(prefix->addr), prefix->len, lifetime, format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime * USEC_PER_SEC, USEC_PER_SEC)); } @@ -473,7 +473,7 @@ static int icmp6_ra_prefix_update(sd_icmp6_nd *nd, ssize_t len, return r; } -static int icmp6_ra_parse(sd_icmp6_nd *nd, struct nd_router_advert *ra, +static int icmp6_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, ssize_t len) { void *opt; struct nd_opt_hdr *opt_hdr; @@ -535,11 +535,11 @@ static int icmp6_ra_parse(sd_icmp6_nd *nd, struct nd_router_advert *ra, } static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - sd_icmp6_nd *nd = userdata; + sd_ndisc *nd = userdata; int r, buflen = 0; ssize_t len; _cleanup_free_ struct nd_router_advert *ra = NULL; - int event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE; + int event = SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE; assert(s); assert(nd); @@ -570,16 +570,16 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; if (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER ) - event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER; + event = SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER; if (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) - event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED; + event = SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED; log_icmp6_nd(nd, "Received Router Advertisement flags %s/%s", ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED? "MANAGED": "none", ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER? "OTHER": "none"); - if (event != SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE) { + if (event != SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE) { r = icmp6_ra_parse(nd, ra, len); if (r < 0) { log_icmp6_nd(nd, "Could not parse Router Advertisement: %s", @@ -594,7 +594,7 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r } static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, void *userdata) { - sd_icmp6_nd *nd = userdata; + sd_ndisc *nd = userdata; uint64_t time_now, next_timeout; struct ether_addr unset = { }; struct ether_addr *addr = NULL; @@ -607,7 +607,7 @@ static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, nd->timeout = sd_event_source_unref(nd->timeout); if (nd->nd_sent >= ICMP6_MAX_ROUTER_SOLICITATIONS) { - icmp6_nd_notify(nd, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT); + icmp6_nd_notify(nd, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT); nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; } else { if (memcmp(&nd->mac_addr, &unset, sizeof(struct ether_addr))) @@ -656,7 +656,7 @@ static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, return 0; } -int sd_icmp6_nd_stop(sd_icmp6_nd *nd) { +int sd_ndisc_stop(sd_ndisc *nd) { assert_return(nd, -EINVAL); assert_return(nd->event, -EINVAL); @@ -669,7 +669,7 @@ int sd_icmp6_nd_stop(sd_icmp6_nd *nd) { return 0; } -int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd) { +int sd_ndisc_router_discovery_start(sd_ndisc *nd) { int r; assert(nd); diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c index 49305e297b..6c79e89881 100644 --- a/src/libsystemd-network/test-ndisc-rs.c +++ b/src/libsystemd-network/test-ndisc-rs.c @@ -70,7 +70,7 @@ static int send_ra_short_prefix(uint8_t flags) { return 0; } -static void test_short_prefix_cb(sd_icmp6_nd *nd, int event, void *userdata) { +static void test_short_prefix_cb(sd_ndisc *nd, int event, void *userdata) { sd_event *e = userdata; struct { struct in6_addr addr; @@ -105,12 +105,12 @@ static void test_short_prefix_cb(sd_icmp6_nd *nd, int event, void *userdata) { addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]); if (addrs[i].success) { - assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, + assert_se(sd_ndisc_get_prefixlen(nd, &addrs[i].addr, &prefixlen) >= 0); assert_se(addrs[i].prefixlen == prefixlen); printf("/%d onlink\n", prefixlen); } else { - assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, + assert_se(sd_ndisc_get_prefixlen(nd, &addrs[i].addr, &prefixlen) == -EADDRNOTAVAIL); printf("/128 offlink\n"); } @@ -154,7 +154,7 @@ static int send_ra_prefixes(uint8_t flags) { return 0; } -static void test_prefixes_cb(sd_icmp6_nd *nd, int event, void *userdata) { +static void test_prefixes_cb(sd_ndisc *nd, int event, void *userdata) { sd_event *e = userdata; struct { struct in6_addr addr; @@ -189,26 +189,26 @@ static void test_prefixes_cb(sd_icmp6_nd *nd, int event, void *userdata) { addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]); if (addrs[i].success) { - assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, + assert_se(sd_ndisc_get_prefixlen(nd, &addrs[i].addr, &prefixlen) >= 0); assert_se(addrs[i].prefixlen == prefixlen); printf("/%d onlink\n", prefixlen); } else { - assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, + assert_se(sd_ndisc_get_prefixlen(nd, &addrs[i].addr, &prefixlen) == -EADDRNOTAVAIL); printf("/128 offlink\n"); } } send_ra_function = send_ra_short_prefix; - assert_se(sd_icmp6_nd_set_callback(nd, test_short_prefix_cb, e) >= 0); - assert_se(sd_icmp6_nd_stop(nd) >= 0); - assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); + assert_se(sd_ndisc_set_callback(nd, test_short_prefix_cb, e) >= 0); + assert_se(sd_ndisc_stop(nd) >= 0); + assert_se(sd_ndisc_router_discovery_start(nd) >= 0); } static void test_prefixes(void) { sd_event *e; - sd_icmp6_nd *nd; + sd_ndisc *nd; if (verbose) printf("* %s\n", __FUNCTION__); @@ -217,20 +217,20 @@ static void test_prefixes(void) { assert_se(sd_event_new(&e) >= 0); - assert_se(sd_icmp6_nd_new(&nd) >= 0); + assert_se(sd_ndisc_new(&nd) >= 0); assert_se(nd); - assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0); + assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0); - assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0); - assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0); - assert_se(sd_icmp6_nd_set_callback(nd, test_prefixes_cb, e) >= 0); + assert_se(sd_ndisc_set_index(nd, 42) >= 0); + assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0); + assert_se(sd_ndisc_set_callback(nd, test_prefixes_cb, e) >= 0); - assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); + assert_se(sd_ndisc_router_discovery_start(nd) >= 0); sd_event_loop(e); - nd = sd_icmp6_nd_unref(nd); + nd = sd_ndisc_unref(nd); assert_se(!nd); close(test_fd[1]); @@ -270,16 +270,16 @@ int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr * return send_ra_function(0); } -static void test_rs_done(sd_icmp6_nd *nd, int event, void *userdata) { +static void test_rs_done(sd_ndisc *nd, int event, void *userdata) { sd_event *e = userdata; static int idx = 0; struct { uint8_t flag; int event; } flag_event[] = { - { 0, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE }, - { ND_RA_FLAG_OTHER, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER }, - { ND_RA_FLAG_MANAGED, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED } + { 0, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE }, + { ND_RA_FLAG_OTHER, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER }, + { ND_RA_FLAG_MANAGED, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED } }; uint32_t mtu; @@ -296,14 +296,14 @@ static void test_rs_done(sd_icmp6_nd *nd, int event, void *userdata) { return; } - assert_se(sd_icmp6_ra_get_mtu(nd, &mtu) == -ENOMSG); + assert_se(sd_ndisc_get_mtu(nd, &mtu) == -ENOMSG); sd_event_exit(e, 0); } static void test_rs(void) { sd_event *e; - sd_icmp6_nd *nd; + sd_ndisc *nd; usec_t time_now = now(clock_boottime_or_monotonic()); if (verbose) @@ -313,30 +313,30 @@ static void test_rs(void) { assert_se(sd_event_new(&e) >= 0); - assert_se(sd_icmp6_nd_new(&nd) >= 0); + assert_se(sd_ndisc_new(&nd) >= 0); assert_se(nd); - assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0); + assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0); - assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0); - assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0); - assert_se(sd_icmp6_nd_set_callback(nd, test_rs_done, e) >= 0); + assert_se(sd_ndisc_set_index(nd, 42) >= 0); + assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0); + assert_se(sd_ndisc_set_callback(nd, test_rs_done, e) >= 0); assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(), time_now + 2 *USEC_PER_SEC, 0, test_rs_hangcheck, NULL) >= 0); - assert_se(sd_icmp6_nd_stop(nd) >= 0); - assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); - assert_se(sd_icmp6_nd_stop(nd) >= 0); + assert_se(sd_ndisc_stop(nd) >= 0); + assert_se(sd_ndisc_router_discovery_start(nd) >= 0); + assert_se(sd_ndisc_stop(nd) >= 0); - assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); + assert_se(sd_ndisc_router_discovery_start(nd) >= 0); sd_event_loop(e); test_hangcheck = sd_event_source_unref(test_hangcheck); - nd = sd_icmp6_nd_unref(nd); + nd = sd_ndisc_unref(nd); assert_se(!nd); close(test_fd[1]); diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index e572ad4595..0023c51b86 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -83,8 +83,8 @@ static int dhcp6_address_change(Link *link, struct in6_addr *ip6_addr, addr->cinfo.ifa_valid = lifetime_valid; log_link_info(link, - "DHCPv6 address "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d timeout preferred %d valid %d", - SD_ICMP6_ND_ADDRESS_FORMAT_VAL(addr->in_addr.in6), + "DHCPv6 address "SD_NDISC_ADDRESS_FORMAT_STR"/%d timeout preferred %d valid %d", + SD_NDISC_ADDRESS_FORMAT_VAL(addr->in_addr.in6), addr->prefixlen, lifetime_preferred, lifetime_valid); r = address_configure(addr, link, dhcp6_address_handler, true); @@ -111,7 +111,7 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) { &lifetime_preferred, &lifetime_valid) >= 0) { - r = sd_icmp6_ra_get_prefixlen(link->icmp6_router_discovery, + r = sd_ndisc_get_prefixlen(link->icmp6_router_discovery, &ip6_addr, &prefixlen); if (r < 0 && r != -EADDRNOTAVAIL) { log_link_warning_errno(link, r, "Could not get prefix information: %m"); @@ -184,9 +184,9 @@ static int dhcp6_configure(Link *link, int event) { bool information_request; assert_return(link, -EINVAL); - assert_return(IN_SET(event, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED), -EINVAL); + assert_return(IN_SET(event, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT, + SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER, + SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED), -EINVAL); link->dhcp6_configured = false; @@ -198,7 +198,7 @@ static int dhcp6_configure(Link *link, int event) { goto error; } - if (information_request && event != SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER) { + if (information_request && event != SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER) { r = sd_dhcp6_client_stop(link->dhcp6_client); if (r < 0) { log_link_warning_errno(link, r, "Could not stop DHCPv6 while setting Managed mode: %m"); @@ -249,7 +249,7 @@ static int dhcp6_configure(Link *link, int event) { if (r < 0) goto error; - if (event == SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER) { + if (event == SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER) { r = sd_dhcp6_client_set_information_request(link->dhcp6_client, true); if (r < 0) @@ -274,7 +274,7 @@ static int dhcp6_prefix_expired(Link *link) { uint8_t expired_prefixlen; uint32_t lifetime_preferred, lifetime_valid; - r = sd_icmp6_ra_get_expired_prefix(link->icmp6_router_discovery, + r = sd_ndisc_get_expired_prefix(link->icmp6_router_discovery, &expired_prefix, &expired_prefixlen); if (r < 0) return r; @@ -283,8 +283,8 @@ static int dhcp6_prefix_expired(Link *link) { if (r < 0) return r; - log_link_info(link, "IPv6 prefix "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d expired", - SD_ICMP6_ND_ADDRESS_FORMAT_VAL(*expired_prefix), + log_link_info(link, "IPv6 prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d expired", + SD_NDISC_ADDRESS_FORMAT_VAL(*expired_prefix), expired_prefixlen); sd_dhcp6_lease_reset_address_iter(lease); @@ -293,12 +293,12 @@ static int dhcp6_prefix_expired(Link *link) { &lifetime_preferred, &lifetime_valid) >= 0) { - r = sd_icmp6_prefix_match(expired_prefix, expired_prefixlen, + r = sd_ndisc_prefix_match(expired_prefix, expired_prefixlen, &ip6_addr); if (r < 0) continue; - log_link_info(link, "IPv6 prefix length updated "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d", SD_ICMP6_ND_ADDRESS_FORMAT_VAL(ip6_addr), 128); + log_link_info(link, "IPv6 prefix length updated "SD_NDISC_ADDRESS_FORMAT_STR"/%d", SD_NDISC_ADDRESS_FORMAT_VAL(ip6_addr), 128); dhcp6_address_change(link, &ip6_addr, 128, lifetime_preferred, lifetime_valid); } @@ -306,7 +306,7 @@ static int dhcp6_prefix_expired(Link *link) { return 0; } -static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) { +static void icmp6_router_handler(sd_ndisc *nd, int event, void *userdata) { Link *link = userdata; assert(link); @@ -317,17 +317,17 @@ static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) { return; switch(event) { - case SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE: + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE: return; - case SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT: - case SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER: - case SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED: + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT: + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER: + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED: dhcp6_configure(link, event); break; - case SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED: + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED: if (!link->rtnl_extended_attrs) dhcp6_prefix_expired(link); @@ -349,23 +349,23 @@ int icmp6_configure(Link *link) { assert_return(link, -EINVAL); - r = sd_icmp6_nd_new(&link->icmp6_router_discovery); + r = sd_ndisc_new(&link->icmp6_router_discovery); if (r < 0) return r; - r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery, NULL, 0); + r = sd_ndisc_attach_event(link->icmp6_router_discovery, NULL, 0); if (r < 0) return r; - r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery, &link->mac); + r = sd_ndisc_set_mac(link->icmp6_router_discovery, &link->mac); if (r < 0) return r; - r = sd_icmp6_nd_set_index(link->icmp6_router_discovery, link->ifindex); + r = sd_ndisc_set_index(link->icmp6_router_discovery, link->ifindex); if (r < 0) return r; - r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery, + r = sd_ndisc_set_callback(link->icmp6_router_discovery, icmp6_router_handler, link); return r; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index ec4b082542..c46ab9b798 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -370,7 +370,7 @@ static void link_free(Link *link) { sd_ipv4ll_unref(link->ipv4ll); sd_dhcp6_client_unref(link->dhcp6_client); - sd_icmp6_nd_unref(link->icmp6_router_discovery); + sd_ndisc_unref(link->icmp6_router_discovery); if (link->manager) hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)); @@ -488,7 +488,7 @@ static int link_stop_clients(Link *link) { r = log_link_warning_errno(link, r, "Could not stop DHCPv6 client: %m"); } - k = sd_icmp6_nd_stop(link->icmp6_router_discovery); + k = sd_ndisc_stop(link->icmp6_router_discovery); if (k < 0) r = log_link_warning_errno(link, r, "Could not stop ICMPv6 router discovery: %m"); } @@ -1242,7 +1242,7 @@ static int link_acquire_conf(Link *link) { log_link_debug(link, "Discovering IPv6 routers"); - r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery); + r = sd_ndisc_router_discovery_start(link->icmp6_router_discovery); if (r < 0) return log_link_warning_errno(link, r, "Could not start IPv6 router discovery: %m"); } diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 5bba313049..668b636620 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -104,7 +104,7 @@ struct Link { sd_dhcp_server *dhcp_server; - sd_icmp6_nd *icmp6_router_discovery; + sd_ndisc *icmp6_router_discovery; sd_dhcp6_client *dhcp6_client; bool rtnl_extended_attrs; diff --git a/src/systemd/sd-ndisc.h b/src/systemd/sd-ndisc.h index 240feb7bbe..8cee7343b5 100644 --- a/src/systemd/sd-ndisc.h +++ b/src/systemd/sd-ndisc.h @@ -27,46 +27,46 @@ #include "sd-event.h" enum { - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE = 0, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT = 1, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER = 2, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED = 3, - SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED = 4, + SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE = 0, + SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT = 1, + SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER = 2, + SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED = 3, + SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED = 4, }; -typedef struct sd_icmp6_nd sd_icmp6_nd; +typedef struct sd_ndisc sd_ndisc; -typedef void(*sd_icmp6_nd_callback_t)(sd_icmp6_nd *nd, int event, +typedef void(*sd_ndisc_callback_t)(sd_ndisc *nd, int event, void *userdata); -int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t cb, +int sd_ndisc_set_callback(sd_ndisc *nd, sd_ndisc_callback_t cb, void *userdata); -int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index); -int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr); +int sd_ndisc_set_index(sd_ndisc *nd, int interface_index); +int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr); -int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority); -int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd); -sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd); +int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int priority); +int sd_ndisc_detach_event(sd_ndisc *nd); +sd_event *sd_ndisc_get_event(sd_ndisc *nd); -sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd); -sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd); -int sd_icmp6_nd_new(sd_icmp6_nd **ret); +sd_ndisc *sd_ndisc_ref(sd_ndisc *nd); +sd_ndisc *sd_ndisc_unref(sd_ndisc *nd); +int sd_ndisc_new(sd_ndisc **ret); -int sd_icmp6_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, +int sd_ndisc_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, struct in6_addr *addr); -int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu); -int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr, +int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu); +int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, uint8_t *prefixlen); -int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, +int sd_ndisc_get_expired_prefix(sd_ndisc *nd, struct in6_addr **addr, uint8_t *prefixlen); -int sd_icmp6_nd_stop(sd_icmp6_nd *nd); -int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd); +int sd_ndisc_stop(sd_ndisc *nd); +int sd_ndisc_router_discovery_start(sd_ndisc *nd); -#define SD_ICMP6_ND_ADDRESS_FORMAT_STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" +#define SD_NDISC_ADDRESS_FORMAT_STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" -#define SD_ICMP6_ND_ADDRESS_FORMAT_VAL(address) \ +#define SD_NDISC_ADDRESS_FORMAT_VAL(address) \ be16toh((address).s6_addr16[0]), \ be16toh((address).s6_addr16[1]), \ be16toh((address).s6_addr16[2]), \ -- cgit v1.2.3-54-g00ecf From de1e9928f137f4d17f463956a7612d9676c393aa Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 16 Oct 2015 17:34:58 +0200 Subject: networkd: rename icmp6 to ndisc --- src/network/networkd-dhcp6.c | 20 ++++++++++---------- src/network/networkd-link.c | 12 ++++++------ src/network/networkd-link.h | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 0023c51b86..6092fb8dc6 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -111,7 +111,7 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) { &lifetime_preferred, &lifetime_valid) >= 0) { - r = sd_ndisc_get_prefixlen(link->icmp6_router_discovery, + r = sd_ndisc_get_prefixlen(link->ndisc_router_discovery, &ip6_addr, &prefixlen); if (r < 0 && r != -EADDRNOTAVAIL) { log_link_warning_errno(link, r, "Could not get prefix information: %m"); @@ -274,7 +274,7 @@ static int dhcp6_prefix_expired(Link *link) { uint8_t expired_prefixlen; uint32_t lifetime_preferred, lifetime_valid; - r = sd_ndisc_get_expired_prefix(link->icmp6_router_discovery, + r = sd_ndisc_get_expired_prefix(link->ndisc_router_discovery, &expired_prefix, &expired_prefixlen); if (r < 0) return r; @@ -306,7 +306,7 @@ static int dhcp6_prefix_expired(Link *link) { return 0; } -static void icmp6_router_handler(sd_ndisc *nd, int event, void *userdata) { +static void ndisc_router_handler(sd_ndisc *nd, int event, void *userdata) { Link *link = userdata; assert(link); @@ -344,29 +344,29 @@ static void icmp6_router_handler(sd_ndisc *nd, int event, void *userdata) { } -int icmp6_configure(Link *link) { +int ndisc_configure(Link *link) { int r; assert_return(link, -EINVAL); - r = sd_ndisc_new(&link->icmp6_router_discovery); + r = sd_ndisc_new(&link->ndisc_router_discovery); if (r < 0) return r; - r = sd_ndisc_attach_event(link->icmp6_router_discovery, NULL, 0); + r = sd_ndisc_attach_event(link->ndisc_router_discovery, NULL, 0); if (r < 0) return r; - r = sd_ndisc_set_mac(link->icmp6_router_discovery, &link->mac); + r = sd_ndisc_set_mac(link->ndisc_router_discovery, &link->mac); if (r < 0) return r; - r = sd_ndisc_set_index(link->icmp6_router_discovery, link->ifindex); + r = sd_ndisc_set_index(link->ndisc_router_discovery, link->ifindex); if (r < 0) return r; - r = sd_ndisc_set_callback(link->icmp6_router_discovery, - icmp6_router_handler, link); + r = sd_ndisc_set_callback(link->ndisc_router_discovery, + ndisc_router_handler, link); return r; } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index c46ab9b798..732a0c438d 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -370,7 +370,7 @@ static void link_free(Link *link) { sd_ipv4ll_unref(link->ipv4ll); sd_dhcp6_client_unref(link->dhcp6_client); - sd_ndisc_unref(link->icmp6_router_discovery); + sd_ndisc_unref(link->ndisc_router_discovery); if (link->manager) hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)); @@ -481,14 +481,14 @@ static int link_stop_clients(Link *link) { r = log_link_warning_errno(link, r, "Could not stop IPv4 link-local: %m"); } - if(link->icmp6_router_discovery) { + if(link->ndisc_router_discovery) { if (link->dhcp6_client) { k = sd_dhcp6_client_stop(link->dhcp6_client); if (k < 0) r = log_link_warning_errno(link, r, "Could not stop DHCPv6 client: %m"); } - k = sd_ndisc_stop(link->icmp6_router_discovery); + k = sd_ndisc_stop(link->ndisc_router_discovery); if (k < 0) r = log_link_warning_errno(link, r, "Could not stop ICMPv6 router discovery: %m"); } @@ -1238,11 +1238,11 @@ static int link_acquire_conf(Link *link) { } if (link_dhcp6_enabled(link)) { - assert(link->icmp6_router_discovery); + assert(link->ndisc_router_discovery); log_link_debug(link, "Discovering IPv6 routers"); - r = sd_ndisc_router_discovery_start(link->icmp6_router_discovery); + r = sd_ndisc_router_discovery_start(link->ndisc_router_discovery); if (r < 0) return log_link_warning_errno(link, r, "Could not start IPv6 router discovery: %m"); } @@ -2002,7 +2002,7 @@ static int link_configure(Link *link) { } if (link_dhcp6_enabled(link)) { - r = icmp6_configure(link); + r = ndisc_configure(link); if (r < 0) return r; } diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 668b636620..f13d904c8e 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -104,7 +104,7 @@ struct Link { sd_dhcp_server *dhcp_server; - sd_ndisc *icmp6_router_discovery; + sd_ndisc *ndisc_router_discovery; sd_dhcp6_client *dhcp6_client; bool rtnl_extended_attrs; @@ -145,7 +145,7 @@ int link_set_timezone(Link *link, const char *timezone); int ipv4ll_configure(Link *link); int dhcp4_configure(Link *link); -int icmp6_configure(Link *link); +int ndisc_configure(Link *link); bool link_lldp_enabled(Link *link); bool link_ipv4ll_enabled(Link *link); -- cgit v1.2.3-54-g00ecf From 940367a0abb4cc4460922cc2fb933ba278a2afbb Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 16 Oct 2015 18:09:10 +0200 Subject: libsystemd-network: split icm6-util.[ch] out of dhcp6 code --- Makefile.am | 4 +- src/libsystemd-network/dhcp6-internal.h | 3 - src/libsystemd-network/dhcp6-network.c | 97 ------------------------ src/libsystemd-network/icmp6-util.c | 129 ++++++++++++++++++++++++++++++++ src/libsystemd-network/icmp6-util.h | 27 +++++++ src/libsystemd-network/sd-ndisc.c | 9 ++- src/libsystemd-network/test-ndisc-rs.c | 6 +- 7 files changed, 167 insertions(+), 108 deletions(-) create mode 100644 src/libsystemd-network/icmp6-util.c create mode 100644 src/libsystemd-network/icmp6-util.h (limited to 'src') diff --git a/Makefile.am b/Makefile.am index eba47e4e12..f309eac10f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3237,6 +3237,8 @@ libsystemd_network_la_SOURCES = \ src/libsystemd-network/network-internal.c \ src/libsystemd-network/network-internal.h \ src/libsystemd-network/sd-ndisc.c \ + src/libsystemd-network/icmp6-util.h \ + src/libsystemd-network/icmp6-util.c \ src/libsystemd-network/sd-dhcp6-client.c \ src/libsystemd-network/dhcp6-internal.h \ src/libsystemd-network/dhcp6-protocol.h \ @@ -3323,7 +3325,7 @@ test_pppoe_LDADD = \ test_ndisc_rs_SOURCES = \ src/systemd/sd-dhcp6-client.h \ src/systemd/sd-ndisc.h \ - src/libsystemd-network/dhcp6-internal.h \ + src/libsystemd-network/icmp6-util.h \ src/libsystemd-network/test-ndisc-rs.c \ src/libsystemd-network/dhcp-identifier.h \ src/libsystemd-network/dhcp-identifier.c diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h index 83e8192f58..eeff74fbb9 100644 --- a/src/libsystemd-network/dhcp6-internal.h +++ b/src/libsystemd-network/dhcp6-internal.h @@ -58,9 +58,6 @@ typedef struct DHCP6IA DHCP6IA; #define log_dhcp6_client(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) -int dhcp_network_icmp6_bind_router_solicitation(int index); -int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr); - int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, size_t optlen, const void *optval); int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia); diff --git a/src/libsystemd-network/dhcp6-network.c b/src/libsystemd-network/dhcp6-network.c index 187975364b..ccb8363e77 100644 --- a/src/libsystemd-network/dhcp6-network.c +++ b/src/libsystemd-network/dhcp6-network.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "socket-util.h" @@ -33,102 +32,6 @@ #include "dhcp6-internal.h" #include "dhcp6-protocol.h" -#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \ - { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } } - -#define IN6ADDR_ALL_NODES_MULTICAST_INIT \ - { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } - -int dhcp_network_icmp6_bind_router_solicitation(int index) { - struct icmp6_filter filter = { }; - struct ipv6_mreq mreq = { - .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT, - .ipv6mr_interface = index, - }; - _cleanup_close_ int s = -1; - int r, zero = 0, hops = 255; - - s = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, - IPPROTO_ICMPV6); - if (s < 0) - return -errno; - - ICMP6_FILTER_SETBLOCKALL(&filter); - ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); - r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, - sizeof(filter)); - if (r < 0) - return -errno; - - /* RFC 3315, section 6.7, bullet point 2 may indicate that an - IPV6_PKTINFO socket option also applies for ICMPv6 multicast. - Empirical experiments indicates otherwise and therefore an - IPV6_MULTICAST_IF socket option is used here instead */ - r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &index, - sizeof(index)); - if (r < 0) - return -errno; - - r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &zero, - sizeof(zero)); - if (r < 0) - return -errno; - - r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, - sizeof(hops)); - if (r < 0) - return -errno; - - r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, - sizeof(mreq)); - if (r < 0) - return -errno; - - r = s; - s = -1; - return r; -} - -int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) { - struct sockaddr_in6 dst = { - .sin6_family = AF_INET6, - .sin6_addr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT, - }; - struct { - struct nd_router_solicit rs; - struct nd_opt_hdr rs_opt; - struct ether_addr rs_opt_mac; - } _packed_ rs = { - .rs.nd_rs_type = ND_ROUTER_SOLICIT, - }; - struct iovec iov[1] = { - { &rs, }, - }; - struct msghdr msg = { - .msg_name = &dst, - .msg_namelen = sizeof(dst), - .msg_iov = iov, - .msg_iovlen = 1, - }; - int r; - - if (ether_addr) { - memcpy(&rs.rs_opt_mac, ether_addr, ETH_ALEN); - rs.rs_opt.nd_opt_type = ND_OPT_SOURCE_LINKADDR; - rs.rs_opt.nd_opt_len = 1; - iov[0].iov_len = sizeof(rs); - } else - iov[0].iov_len = sizeof(rs.rs); - - r = sendmsg(s, &msg, 0); - if (r < 0) - return -errno; - - return 0; -} - int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) { struct in6_pktinfo pktinfo = { .ipi6_ifindex = index, diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c new file mode 100644 index 0000000000..140429b1e9 --- /dev/null +++ b/src/libsystemd-network/icmp6-util.c @@ -0,0 +1,129 @@ +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "socket-util.h" + +#include "icmp6-util.h" + +#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \ + { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } } + +#define IN6ADDR_ALL_NODES_MULTICAST_INIT \ + { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } + +int icmp6_bind_router_solicitation(int index) { + struct icmp6_filter filter = { }; + struct ipv6_mreq mreq = { + .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT, + .ipv6mr_interface = index, + }; + _cleanup_close_ int s = -1; + int r, zero = 0, hops = 255; + + s = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, + IPPROTO_ICMPV6); + if (s < 0) + return -errno; + + ICMP6_FILTER_SETBLOCKALL(&filter); + ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); + r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, + sizeof(filter)); + if (r < 0) + return -errno; + + /* RFC 3315, section 6.7, bullet point 2 may indicate that an + IPV6_PKTINFO socket option also applies for ICMPv6 multicast. + Empirical experiments indicates otherwise and therefore an + IPV6_MULTICAST_IF socket option is used here instead */ + r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &index, + sizeof(index)); + if (r < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &zero, + sizeof(zero)); + if (r < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, + sizeof(hops)); + if (r < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, + sizeof(mreq)); + if (r < 0) + return -errno; + + r = s; + s = -1; + return r; +} + +int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) { + struct sockaddr_in6 dst = { + .sin6_family = AF_INET6, + .sin6_addr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT, + }; + struct { + struct nd_router_solicit rs; + struct nd_opt_hdr rs_opt; + struct ether_addr rs_opt_mac; + } _packed_ rs = { + .rs.nd_rs_type = ND_ROUTER_SOLICIT, + }; + struct iovec iov[1] = { + { &rs, }, + }; + struct msghdr msg = { + .msg_name = &dst, + .msg_namelen = sizeof(dst), + .msg_iov = iov, + .msg_iovlen = 1, + }; + int r; + + if (ether_addr) { + memcpy(&rs.rs_opt_mac, ether_addr, ETH_ALEN); + rs.rs_opt.nd_opt_type = ND_OPT_SOURCE_LINKADDR; + rs.rs_opt.nd_opt_len = 1; + iov[0].iov_len = sizeof(rs); + } else + iov[0].iov_len = sizeof(rs.rs); + + r = sendmsg(s, &msg, 0); + if (r < 0) + return -errno; + + return 0; +} diff --git a/src/libsystemd-network/icmp6-util.h b/src/libsystemd-network/icmp6-util.h new file mode 100644 index 0000000000..4eb17e152e --- /dev/null +++ b/src/libsystemd-network/icmp6-util.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014-2015 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +int icmp6_bind_router_solicitation(int index); +int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr); diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index eb6529287f..2b979f3091 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -24,10 +24,11 @@ #include #include -#include "socket-util.h" #include "async.h" +#include "list.h" +#include "socket-util.h" -#include "dhcp6-internal.h" +#include "icmp6-util.h" #include "sd-ndisc.h" #define ICMP6_ROUTER_SOLICITATION_INTERVAL 4 * USEC_PER_SEC @@ -613,7 +614,7 @@ static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, if (memcmp(&nd->mac_addr, &unset, sizeof(struct ether_addr))) addr = &nd->mac_addr; - r = dhcp_network_icmp6_send_router_solicitation(nd->fd, addr); + r = icmp6_send_router_solicitation(nd->fd, addr); if (r < 0) log_icmp6_nd(nd, "Error sending Router Solicitation"); else { @@ -681,7 +682,7 @@ int sd_ndisc_router_discovery_start(sd_ndisc *nd) { if (nd->index < 1) return -EINVAL; - r = dhcp_network_icmp6_bind_router_solicitation(nd->index); + r = icmp6_bind_router_solicitation(nd->index); if (r < 0) return r; diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c index 6c79e89881..0bb488cd91 100644 --- a/src/libsystemd-network/test-ndisc-rs.c +++ b/src/libsystemd-network/test-ndisc-rs.c @@ -23,7 +23,7 @@ #include "socket-util.h" -#include "dhcp6-internal.h" +#include "icmp6-util.h" #include "sd-ndisc.h" static struct ether_addr mac_addr = { @@ -44,7 +44,7 @@ static int test_rs_hangcheck(sd_event_source *s, uint64_t usec, return 0; } -int dhcp_network_icmp6_bind_router_solicitation(int index) { +int icmp6_bind_router_solicitation(int index) { assert_se(index == 42); if (socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) < 0) @@ -266,7 +266,7 @@ static int send_ra(uint8_t flags) { return 0; } -int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) { +int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) { return send_ra_function(0); } -- cgit v1.2.3-54-g00ecf From 46ec668714b5fcc7c11a7b974a7d64fc13ab62c7 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 16 Oct 2015 19:17:50 +0200 Subject: sd-ndisc: rename icmp6 to ndisc throughout the code --- src/libsystemd-network/sd-ndisc.c | 186 +++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 2b979f3091..92c872e166 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -31,25 +31,25 @@ #include "icmp6-util.h" #include "sd-ndisc.h" -#define ICMP6_ROUTER_SOLICITATION_INTERVAL 4 * USEC_PER_SEC -#define ICMP6_MAX_ROUTER_SOLICITATIONS 3 +#define NDISC_ROUTER_SOLICITATION_INTERVAL 4 * USEC_PER_SEC +#define NDISC_MAX_ROUTER_SOLICITATIONS 3 -enum icmp6_nd_state { - ICMP6_NEIGHBOR_DISCOVERY_IDLE = 0, - ICMP6_ROUTER_SOLICITATION_SENT = 10, - ICMP6_ROUTER_ADVERTISMENT_LISTEN = 11, +enum NDiscState { + NDISC_STATE_IDLE = 0, + NDISC_STATE_SOLICITATION_SENT = 10, + NDISC_STATE_ADVERTISMENT_LISTEN = 11, }; #define IP6_MIN_MTU (unsigned)1280 -#define ICMP6_ND_RECV_SIZE (IP6_MIN_MTU - sizeof(struct ip6_hdr)) -#define ICMP6_OPT_LEN_UNITS 8 +#define ICMP6_RECV_SIZE (IP6_MIN_MTU - sizeof(struct ip6_hdr)) +#define NDISC_OPT_LEN_UNITS 8 -typedef struct ICMP6Prefix ICMP6Prefix; +typedef struct NDiscPrefix NDiscPrefix; -struct ICMP6Prefix { +struct NDiscPrefix { unsigned n_ref; - LIST_FIELDS(ICMP6Prefix, prefixes); + LIST_FIELDS(NDiscPrefix, prefixes); uint8_t len; sd_event_source *timeout_valid; @@ -59,14 +59,14 @@ struct ICMP6Prefix { struct sd_ndisc { unsigned n_ref; - enum icmp6_nd_state state; + enum NDiscState state; sd_event *event; int event_priority; int index; struct ether_addr mac_addr; uint32_t mtu; - ICMP6Prefix *expired_prefix; - LIST_HEAD(ICMP6Prefix, prefixes); + NDiscPrefix *expired_prefix; + LIST_HEAD(NDiscPrefix, prefixes); int fd; sd_event_source *recv; sd_event_source *timeout; @@ -75,9 +75,9 @@ struct sd_ndisc { void *userdata; }; -#define log_icmp6_nd(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__) +#define log_ndisc(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "NDisc CLIENT: " fmt, ##__VA_ARGS__) -static ICMP6Prefix *icmp6_prefix_unref(ICMP6Prefix *prefix) { +static NDiscPrefix *ndisc_prefix_unref(NDiscPrefix *prefix) { if (!prefix) return NULL; @@ -93,12 +93,12 @@ static ICMP6Prefix *icmp6_prefix_unref(ICMP6Prefix *prefix) { return NULL; } -static int icmp6_prefix_new(ICMP6Prefix **ret) { - _cleanup_free_ ICMP6Prefix *prefix = NULL; +static int ndisc_prefix_new(NDiscPrefix **ret) { + _cleanup_free_ NDiscPrefix *prefix = NULL; assert(ret); - prefix = new0(ICMP6Prefix, 1); + prefix = new0(NDiscPrefix, 1); if (!prefix) return -ENOMEM; @@ -111,7 +111,7 @@ static int icmp6_prefix_new(ICMP6Prefix **ret) { return 0; } -static void icmp6_nd_notify(sd_ndisc *nd, int event) { +static void ndisc_notify(sd_ndisc *nd, int event) { if (nd->callback) nd->callback(nd, event, nd->userdata); } @@ -191,7 +191,7 @@ sd_ndisc *sd_ndisc_ref(sd_ndisc *nd) { return nd; } -static int icmp6_nd_init(sd_ndisc *nd) { +static int ndisc_init(sd_ndisc *nd) { assert(nd); nd->recv = sd_event_source_unref(nd->recv); @@ -202,7 +202,7 @@ static int icmp6_nd_init(sd_ndisc *nd) { } sd_ndisc *sd_ndisc_unref(sd_ndisc *nd) { - ICMP6Prefix *prefix, *p; + NDiscPrefix *prefix, *p; if (!nd) return NULL; @@ -213,13 +213,13 @@ sd_ndisc *sd_ndisc_unref(sd_ndisc *nd) { if (nd->n_ref > 0) return NULL; - icmp6_nd_init(nd); + ndisc_init(nd); sd_ndisc_detach_event(nd); LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { LIST_REMOVE(prefixes, nd->prefixes, prefix); - prefix = icmp6_prefix_unref(prefix); + prefix = ndisc_prefix_unref(prefix); } free(nd); @@ -264,10 +264,10 @@ int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu) { return 0; } -static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec, +static int ndisc_prefix_timeout(sd_event_source *s, uint64_t usec, void *userdata) { sd_ndisc *nd = userdata; - ICMP6Prefix *prefix, *p; + NDiscPrefix *prefix, *p; assert(nd); @@ -275,18 +275,18 @@ static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec, if (prefix->timeout_valid != s) continue; - log_icmp6_nd(nd, "Prefix expired "SD_NDISC_ADDRESS_FORMAT_STR"/%d", + log_ndisc(nd, "Prefix expired "SD_NDISC_ADDRESS_FORMAT_STR"/%d", SD_NDISC_ADDRESS_FORMAT_VAL(prefix->addr), prefix->len); LIST_REMOVE(prefixes, nd->prefixes, prefix); nd->expired_prefix = prefix; - icmp6_nd_notify(nd, + ndisc_notify(nd, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED); nd->expired_prefix = NULL; - prefix = icmp6_prefix_unref(prefix); + prefix = ndisc_prefix_unref(prefix); break; } @@ -294,8 +294,8 @@ static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec, return 0; } -static int icmp6_ra_prefix_set_timeout(sd_ndisc *nd, - ICMP6Prefix *prefix, +static int ndisc_prefix_set_timeout(sd_ndisc *nd, + NDiscPrefix *prefix, usec_t valid) { usec_t time_now; int r; @@ -310,7 +310,7 @@ static int icmp6_ra_prefix_set_timeout(sd_ndisc *nd, r = sd_event_add_time(nd->event, &prefix->timeout_valid, clock_boottime_or_monotonic(), time_now + valid, - USEC_PER_SEC, icmp6_ra_prefix_timeout, nd); + USEC_PER_SEC, ndisc_prefix_timeout, nd); if (r < 0) goto error; @@ -320,7 +320,7 @@ static int icmp6_ra_prefix_set_timeout(sd_ndisc *nd, goto error; r = sd_event_source_set_description(prefix->timeout_valid, - "icmp6-prefix-timeout"); + "ndisc-prefix-timeout"); error: if (r < 0) @@ -330,9 +330,9 @@ error: return r; } -static int icmp6_prefix_match(const struct in6_addr *prefix, uint8_t prefixlen, - const struct in6_addr *addr, - uint8_t addr_prefixlen) { +static int prefix_match(const struct in6_addr *prefix, uint8_t prefixlen, + const struct in6_addr *addr, + uint8_t addr_prefixlen) { uint8_t bytes, mask, len; assert_return(prefix, -EINVAL); @@ -350,13 +350,12 @@ static int icmp6_prefix_match(const struct in6_addr *prefix, uint8_t prefixlen, return 0; } -static int icmp6_ra_prefix_match(ICMP6Prefix *head, const struct in6_addr *addr, - uint8_t addr_len, ICMP6Prefix **result) { - ICMP6Prefix *prefix; +static int ndisc_prefix_match(NDiscPrefix *head, const struct in6_addr *addr, + uint8_t addr_len, NDiscPrefix **result) { + NDiscPrefix *prefix; LIST_FOREACH(prefixes, prefix, head) { - if (icmp6_prefix_match(&prefix->addr, prefix->len, addr, - addr_len) >= 0) { + if (prefix_match(&prefix->addr, prefix->len, addr, addr_len) >= 0) { *result = prefix; return 0; } @@ -367,20 +366,19 @@ static int icmp6_ra_prefix_match(ICMP6Prefix *head, const struct in6_addr *addr, int sd_ndisc_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, struct in6_addr *addr) { - return icmp6_prefix_match(prefix, prefixlen, addr, - sizeof(addr->s6_addr) * 8); + return prefix_match(prefix, prefixlen, addr, sizeof(addr->s6_addr) * 8); } int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, uint8_t *prefixlen) { int r; - ICMP6Prefix *prefix; + NDiscPrefix *prefix; assert_return(nd, -EINVAL); assert_return(addr, -EINVAL); assert_return(prefixlen, -EINVAL); - r = icmp6_ra_prefix_match(nd->prefixes, addr, + r = ndisc_prefix_match(nd->prefixes, addr, sizeof(addr->s6_addr) * 8, &prefix); if (r < 0) return r; @@ -404,10 +402,10 @@ int sd_ndisc_get_expired_prefix(sd_ndisc *nd, struct in6_addr **addr, uint8_t *p return 0; } -static int icmp6_ra_prefix_update(sd_ndisc *nd, ssize_t len, +static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, const struct nd_opt_prefix_info *prefix_opt) { int r; - ICMP6Prefix *prefix; + NDiscPrefix *prefix; uint32_t lifetime; char time_string[FORMAT_TIMESPAN_MAX]; @@ -422,7 +420,7 @@ static int icmp6_ra_prefix_update(sd_ndisc *nd, ssize_t len, lifetime = be32toh(prefix_opt->nd_opt_pi_valid_time); - r = icmp6_ra_prefix_match(nd->prefixes, + r = ndisc_prefix_match(nd->prefixes, &prefix_opt->nd_opt_pi_prefix, prefix_opt->nd_opt_pi_prefix_len, &prefix); @@ -433,7 +431,7 @@ static int icmp6_ra_prefix_update(sd_ndisc *nd, ssize_t len, callback will be called immediately to clean up the prefix */ if (r == -EADDRNOTAVAIL) { - r = icmp6_prefix_new(&prefix); + r = ndisc_prefix_new(&prefix); if (r < 0) return r; @@ -442,7 +440,7 @@ static int icmp6_ra_prefix_update(sd_ndisc *nd, ssize_t len, memcpy(&prefix->addr, &prefix_opt->nd_opt_pi_prefix, sizeof(prefix->addr)); - log_icmp6_nd(nd, "New prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", + log_ndisc(nd, "New prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", SD_NDISC_ADDRESS_FORMAT_VAL(prefix->addr), prefix->len, lifetime, format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime * USEC_PER_SEC, USEC_PER_SEC)); @@ -455,7 +453,7 @@ static int icmp6_ra_prefix_update(sd_ndisc *nd, ssize_t len, prefixlen = MIN(prefix->len, prefix_opt->nd_opt_pi_prefix_len); - log_icmp6_nd(nd, "Prefix length mismatch %d/%d using %d", + log_ndisc(nd, "Prefix length mismatch %d/%d using %d", prefix->len, prefix_opt->nd_opt_pi_prefix_len, prefixlen); @@ -463,18 +461,18 @@ static int icmp6_ra_prefix_update(sd_ndisc *nd, ssize_t len, prefix->len = prefixlen; } - log_icmp6_nd(nd, "Update prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", + log_ndisc(nd, "Update prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", SD_NDISC_ADDRESS_FORMAT_VAL(prefix->addr), prefix->len, lifetime, format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime * USEC_PER_SEC, USEC_PER_SEC)); } - r = icmp6_ra_prefix_set_timeout(nd, prefix, lifetime * USEC_PER_SEC); + r = ndisc_prefix_set_timeout(nd, prefix, lifetime * USEC_PER_SEC); return r; } -static int icmp6_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, +static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, ssize_t len) { void *opt; struct nd_opt_hdr *opt_hdr; @@ -483,8 +481,8 @@ static int icmp6_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, assert_return(ra, -EINVAL); len -= sizeof(*ra); - if (len < ICMP6_OPT_LEN_UNITS) { - log_icmp6_nd(nd, "Router Advertisement below minimum length"); + if (len < NDISC_OPT_LEN_UNITS) { + log_ndisc(nd, "Router Advertisement below minimum length"); return -ENOMSG; } @@ -492,7 +490,7 @@ static int icmp6_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, opt = ra + 1; opt_hdr = opt; - while (len != 0 && len >= opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS) { + 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; @@ -509,7 +507,7 @@ static int icmp6_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, if (mtu != nd->mtu) { nd->mtu = MAX(mtu, IP6_MIN_MTU); - log_icmp6_nd(nd, "Router Advertisement link MTU %d using %d", + log_ndisc(nd, "Router Advertisement link MTU %d using %d", mtu, nd->mtu); } @@ -518,24 +516,24 @@ static int icmp6_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, case ND_OPT_PREFIX_INFORMATION: opt_prefix = opt; - icmp6_ra_prefix_update(nd, len, opt_prefix); + ndisc_prefix_update(nd, len, opt_prefix); break; } - len -= opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS; + len -= opt_hdr->nd_opt_len * NDISC_OPT_LEN_UNITS; opt = (void *)((char *)opt + - opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS); + opt_hdr->nd_opt_len * NDISC_OPT_LEN_UNITS); opt_hdr = opt; } if (len > 0) - log_icmp6_nd(nd, "Router Advertisement contains %zd bytes of trailing garbage", len); + log_ndisc(nd, "Router Advertisement contains %zd bytes of trailing garbage", len); return 0; } -static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { +static int ndisc_router_advertisment_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { sd_ndisc *nd = userdata; int r, buflen = 0; ssize_t len; @@ -548,7 +546,7 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r r = ioctl(fd, FIONREAD, &buflen); if (r < 0 || buflen <= 0) - buflen = ICMP6_ND_RECV_SIZE; + buflen = ICMP6_RECV_SIZE; ra = malloc(buflen); if (!ra) @@ -556,7 +554,7 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r len = read(fd, ra, buflen); if (len < 0) { - log_icmp6_nd(nd, "Could not receive message from UDP socket: %m"); + log_ndisc(nd, "Could not receive message from UDP socket: %m"); return 0; } @@ -568,7 +566,7 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r nd->timeout = sd_event_source_unref(nd->timeout); - nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; + nd->state = NDISC_STATE_ADVERTISMENT_LISTEN; if (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER ) event = SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER; @@ -576,25 +574,25 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t r if (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) event = SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED; - log_icmp6_nd(nd, "Received Router Advertisement flags %s/%s", + log_ndisc(nd, "Received Router Advertisement flags %s/%s", ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED? "MANAGED": "none", ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER? "OTHER": "none"); if (event != SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE) { - r = icmp6_ra_parse(nd, ra, len); + r = ndisc_ra_parse(nd, ra, len); if (r < 0) { - log_icmp6_nd(nd, "Could not parse Router Advertisement: %s", + log_ndisc(nd, "Could not parse Router Advertisement: %s", strerror(-r)); return 0; } } - icmp6_nd_notify(nd, event); + ndisc_notify(nd, event); return 0; } -static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, void *userdata) { +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; struct ether_addr unset = { }; @@ -607,49 +605,49 @@ static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, nd->timeout = sd_event_source_unref(nd->timeout); - if (nd->nd_sent >= ICMP6_MAX_ROUTER_SOLICITATIONS) { - icmp6_nd_notify(nd, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT); - nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; + if (nd->nd_sent >= NDISC_MAX_ROUTER_SOLICITATIONS) { + ndisc_notify(nd, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT); + nd->state = NDISC_STATE_ADVERTISMENT_LISTEN; } else { if (memcmp(&nd->mac_addr, &unset, sizeof(struct ether_addr))) addr = &nd->mac_addr; r = icmp6_send_router_solicitation(nd->fd, addr); if (r < 0) - log_icmp6_nd(nd, "Error sending Router Solicitation"); + log_ndisc(nd, "Error sending Router Solicitation"); else { - nd->state = ICMP6_ROUTER_SOLICITATION_SENT; - log_icmp6_nd(nd, "Sent Router Solicitation"); + nd->state = NDISC_STATE_SOLICITATION_SENT; + log_ndisc(nd, "Sent Router Solicitation"); } nd->nd_sent++; r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); if (r < 0) { - icmp6_nd_notify(nd, r); + ndisc_notify(nd, r); return 0; } - next_timeout = time_now + ICMP6_ROUTER_SOLICITATION_INTERVAL; + next_timeout = time_now + NDISC_ROUTER_SOLICITATION_INTERVAL; r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), next_timeout, 0, - icmp6_router_solicitation_timeout, nd); + ndisc_router_solicitation_timeout, nd); if (r < 0) { - icmp6_nd_notify(nd, r); + ndisc_notify(nd, r); return 0; } r = sd_event_source_set_priority(nd->timeout, nd->event_priority); if (r < 0) { - icmp6_nd_notify(nd, r); + ndisc_notify(nd, r); return 0; } - r = sd_event_source_set_description(nd->timeout, "icmp6-timeout"); + r = sd_event_source_set_description(nd->timeout, "ndisc-timeout"); if (r < 0) { - icmp6_nd_notify(nd, r); + ndisc_notify(nd, r); return 0; } } @@ -661,11 +659,11 @@ int sd_ndisc_stop(sd_ndisc *nd) { assert_return(nd, -EINVAL); assert_return(nd->event, -EINVAL); - log_icmp6_nd(client, "Stop ICMPv6"); + log_ndisc(client, "Stop NDisc"); - icmp6_nd_init(nd); + ndisc_init(nd); - nd->state = ICMP6_NEIGHBOR_DISCOVERY_IDLE; + nd->state = NDISC_STATE_IDLE; return 0; } @@ -676,7 +674,7 @@ int sd_ndisc_router_discovery_start(sd_ndisc *nd) { assert(nd); assert(nd->event); - if (nd->state != ICMP6_NEIGHBOR_DISCOVERY_IDLE) + if (nd->state != NDISC_STATE_IDLE) return -EINVAL; if (nd->index < 1) @@ -689,7 +687,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, - icmp6_router_advertisment_recv, nd); + ndisc_router_advertisment_recv, nd); if (r < 0) goto error; @@ -697,12 +695,12 @@ int sd_ndisc_router_discovery_start(sd_ndisc *nd) { if (r < 0) goto error; - r = sd_event_source_set_description(nd->recv, "icmp6-receive-message"); + r = sd_event_source_set_description(nd->recv, "ndisc-receive-message"); if (r < 0) goto error; r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), - 0, 0, icmp6_router_solicitation_timeout, nd); + 0, 0, ndisc_router_solicitation_timeout, nd); if (r < 0) goto error; @@ -710,12 +708,12 @@ int sd_ndisc_router_discovery_start(sd_ndisc *nd) { if (r < 0) goto error; - r = sd_event_source_set_description(nd->timeout, "icmp6-timeout"); + r = sd_event_source_set_description(nd->timeout, "ndisc-timeout"); error: if (r < 0) - icmp6_nd_init(nd); + ndisc_init(nd); else - log_icmp6_nd(client, "Start Router Solicitation"); + log_ndisc(client, "Start Router Solicitation"); return r; } -- cgit v1.2.3-54-g00ecf From ceabaf0fea12d38b15d7c69a5ae4faf90105e543 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 16 Oct 2015 19:28:27 +0200 Subject: networkd: ndisc - make logging messages uniform Refer to Router Discovery rather than ICMPv6. --- src/network/networkd-dhcp6.c | 4 ++-- src/network/networkd-link.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 6092fb8dc6..42a6f382b0 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -335,9 +335,9 @@ static void ndisc_router_handler(sd_ndisc *nd, int event, void *userdata) { default: if (event < 0) - log_link_warning_errno(link, event, "ICMPv6 error: %m"); + log_link_warning_errno(link, event, "IPv6 Neighborhood Discover error: %m"); else - log_link_warning(link, "ICMPv6 unknown event: %d", event); + log_link_warning(link, "IPv6 Neighborhood Discovery unknown event: %d", event); break; } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 732a0c438d..09f4bd7029 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -490,7 +490,7 @@ static int link_stop_clients(Link *link) { k = sd_ndisc_stop(link->ndisc_router_discovery); if (k < 0) - r = log_link_warning_errno(link, r, "Could not stop ICMPv6 router discovery: %m"); + r = log_link_warning_errno(link, r, "Could not stop IPv6 Router Discovery: %m"); } if (link->lldp) { @@ -1244,7 +1244,7 @@ static int link_acquire_conf(Link *link) { r = sd_ndisc_router_discovery_start(link->ndisc_router_discovery); if (r < 0) - return log_link_warning_errno(link, r, "Could not start IPv6 router discovery: %m"); + return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m"); } if (link_lldp_enabled(link)) { -- cgit v1.2.3-54-g00ecf From a13c50e7a33e2b8e0481f725c6272142e6f71751 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 16 Oct 2015 21:09:15 +0200 Subject: networkd: ndisc - split out from dhcp6 code --- Makefile.am | 1 + src/network/networkd-dhcp6.c | 85 ++++----------------------------------- src/network/networkd-link.h | 2 + src/network/networkd-ndisc.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 78 deletions(-) create mode 100644 src/network/networkd-ndisc.c (limited to 'src') diff --git a/Makefile.am b/Makefile.am index f309eac10f..fa25485b73 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5232,6 +5232,7 @@ libnetworkd_core_la_SOURCES = \ src/network/networkd-ipv4ll.c \ src/network/networkd-dhcp4.c \ src/network/networkd-dhcp6.c \ + src/network/networkd-ndisc.c \ src/network/networkd-network.h \ src/network/networkd-network.c \ src/network/networkd-network-bus.c \ diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 42a6f382b0..fa02aa0a3d 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -179,34 +179,29 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) { link_check_ready(link); } -static int dhcp6_configure(Link *link, int event) { +int dhcp6_configure(Link *link, bool inf_req) { int r; bool information_request; assert_return(link, -EINVAL); - assert_return(IN_SET(event, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT, - SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER, - SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED), -EINVAL); link->dhcp6_configured = false; if (link->dhcp6_client) { - r = sd_dhcp6_client_get_information_request(link->dhcp6_client, - &information_request); + r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &information_request); if (r < 0) { log_link_warning_errno(link, r, "Could not get DHCPv6 Information request setting: %m"); goto error; } - if (information_request && event != SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER) { + if (information_request && !inf_req) { r = sd_dhcp6_client_stop(link->dhcp6_client); if (r < 0) { log_link_warning_errno(link, r, "Could not stop DHCPv6 while setting Managed mode: %m"); goto error; } - r = sd_dhcp6_client_set_information_request(link->dhcp6_client, - false); + r = sd_dhcp6_client_set_information_request(link->dhcp6_client, false); if (r < 0) { log_link_warning_errno(link, r, "Could not unset DHCPv6 Information request: %m"); goto error; @@ -249,9 +244,8 @@ static int dhcp6_configure(Link *link, int event) { if (r < 0) goto error; - if (event == SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER) { - r = sd_dhcp6_client_set_information_request(link->dhcp6_client, - true); + if (inf_req) { + r = sd_dhcp6_client_set_information_request(link->dhcp6_client, true); if (r < 0) goto error; } @@ -267,7 +261,7 @@ static int dhcp6_configure(Link *link, int event) { return r; } -static int dhcp6_prefix_expired(Link *link) { +int dhcp6_prefix_expired(Link *link) { int r; sd_dhcp6_lease *lease; struct in6_addr *expired_prefix, ip6_addr; @@ -305,68 +299,3 @@ static int dhcp6_prefix_expired(Link *link) { return 0; } - -static void ndisc_router_handler(sd_ndisc *nd, int event, void *userdata) { - Link *link = userdata; - - assert(link); - assert(link->network); - assert(link->manager); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return; - - switch(event) { - case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE: - return; - - case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT: - case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER: - case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED: - dhcp6_configure(link, event); - - break; - - case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED: - if (!link->rtnl_extended_attrs) - dhcp6_prefix_expired(link); - - break; - - default: - if (event < 0) - log_link_warning_errno(link, event, "IPv6 Neighborhood Discover error: %m"); - else - log_link_warning(link, "IPv6 Neighborhood Discovery unknown event: %d", event); - - break; - } - -} - -int ndisc_configure(Link *link) { - int r; - - assert_return(link, -EINVAL); - - r = sd_ndisc_new(&link->ndisc_router_discovery); - if (r < 0) - return r; - - r = sd_ndisc_attach_event(link->ndisc_router_discovery, NULL, 0); - if (r < 0) - return r; - - r = sd_ndisc_set_mac(link->ndisc_router_discovery, &link->mac); - if (r < 0) - return r; - - r = sd_ndisc_set_index(link->ndisc_router_discovery, link->ifindex); - if (r < 0) - return r; - - r = sd_ndisc_set_callback(link->ndisc_router_discovery, - ndisc_router_handler, link); - - return r; -} diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index f13d904c8e..6bc88157cf 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -145,6 +145,8 @@ int link_set_timezone(Link *link, const char *timezone); int ipv4ll_configure(Link *link); int dhcp4_configure(Link *link); +int dhcp6_configure(Link *link, bool information_request); +int dhcp6_prefix_expired(Link *link); int ndisc_configure(Link *link); bool link_lldp_enabled(Link *link); diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c new file mode 100644 index 0000000000..1721cb36b6 --- /dev/null +++ b/src/network/networkd-ndisc.c @@ -0,0 +1,94 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "networkd-link.h" + +#include "sd-ndisc.h" + +static void ndisc_router_handler(sd_ndisc *nd, int event, void *userdata) { + Link *link = userdata; + + assert(link); + assert(link->network); + assert(link->manager); + + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + return; + + switch(event) { + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE: + return; + + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER: + dhcp6_configure(link, true); + + break; + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT: + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED: + dhcp6_configure(link, false); + + break; + + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED: + if (!link->rtnl_extended_attrs) + dhcp6_prefix_expired(link); + + break; + + default: + if (event < 0) + log_link_warning_errno(link, event, "IPv6 Neighbor Discover error: %m"); + else + log_link_warning(link, "IPv6 Neighbor Discovery unknown event: %d", event); + + break; + } +} + +int ndisc_configure(Link *link) { + int r; + + assert_return(link, -EINVAL); + + r = sd_ndisc_new(&link->ndisc_router_discovery); + if (r < 0) + return r; + + r = sd_ndisc_attach_event(link->ndisc_router_discovery, NULL, 0); + if (r < 0) + return r; + + r = sd_ndisc_set_mac(link->ndisc_router_discovery, &link->mac); + if (r < 0) + return r; + + r = sd_ndisc_set_index(link->ndisc_router_discovery, link->ifindex); + if (r < 0) + return r; + + r = sd_ndisc_set_callback(link->ndisc_router_discovery, + ndisc_router_handler, link); + + return r; +} -- cgit v1.2.3-54-g00ecf From 6d8f6b0b2ae14aee0b02c7e3d1edaeaa2c118056 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 18 Oct 2015 16:59:21 +0200 Subject: networkd: dhcp6 - DHCPv6 addresses should always be /128 The routing information should be configured separately by ND, there is no need to indicate the prefix again in the DHCPv6 addresses. See discussion and related links at issue #1520. --- src/network/networkd-dhcp6.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index fa02aa0a3d..f47ac15dcd 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -64,8 +64,7 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, } static int dhcp6_address_change(Link *link, struct in6_addr *ip6_addr, - uint8_t prefixlen, uint32_t lifetime_preferred, - uint32_t lifetime_valid) { + uint32_t lifetime_preferred, uint32_t lifetime_valid) { int r; _cleanup_address_free_ Address *addr = NULL; @@ -77,7 +76,7 @@ static int dhcp6_address_change(Link *link, struct in6_addr *ip6_addr, memcpy(&addr->in_addr.in6, ip6_addr, sizeof(*ip6_addr)); addr->flags = IFA_F_NOPREFIXROUTE; - addr->prefixlen = prefixlen; + addr->prefixlen = 128; addr->cinfo.ifa_prefered = lifetime_preferred; addr->cinfo.ifa_valid = lifetime_valid; @@ -99,7 +98,6 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) { sd_dhcp6_lease *lease; struct in6_addr ip6_addr; uint32_t lifetime_preferred, lifetime_valid; - uint8_t prefixlen; r = sd_dhcp6_client_get_lease(client, &lease); if (r < 0) @@ -111,18 +109,7 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) { &lifetime_preferred, &lifetime_valid) >= 0) { - r = sd_ndisc_get_prefixlen(link->ndisc_router_discovery, - &ip6_addr, &prefixlen); - if (r < 0 && r != -EADDRNOTAVAIL) { - log_link_warning_errno(link, r, "Could not get prefix information: %m"); - return r; - } - - if (r == -EADDRNOTAVAIL) - prefixlen = 128; - - r = dhcp6_address_change(link, &ip6_addr, prefixlen, - lifetime_preferred, lifetime_valid); + r = dhcp6_address_change(link, &ip6_addr, lifetime_preferred, lifetime_valid); if (r < 0) return r; } @@ -294,7 +281,7 @@ int dhcp6_prefix_expired(Link *link) { log_link_info(link, "IPv6 prefix length updated "SD_NDISC_ADDRESS_FORMAT_STR"/%d", SD_NDISC_ADDRESS_FORMAT_VAL(ip6_addr), 128); - dhcp6_address_change(link, &ip6_addr, 128, lifetime_preferred, lifetime_valid); + dhcp6_address_change(link, &ip6_addr, lifetime_preferred, lifetime_valid); } return 0; -- cgit v1.2.3-54-g00ecf From 9b4d33193af554628c369681404b0c3809a7d6db Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 18 Oct 2015 17:06:31 +0200 Subject: networkd: dhcp6 - do not handle prefix expiration This ressurects 47d45d3cde45d6545367570264e4e3636bc9e345. We now always use /128 prefixes, so there is no need for the DHCPv6 code to know about prefixes expiring. --- src/network/networkd-dhcp6.c | 40 ---------------------------------------- src/network/networkd-link.h | 1 - src/network/networkd-ndisc.c | 7 +------ 3 files changed, 1 insertion(+), 47 deletions(-) (limited to 'src') diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index f47ac15dcd..57c81cb646 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -25,7 +25,6 @@ #include "networkd-link.h" #include "network-internal.h" -#include "sd-ndisc.h" #include "sd-dhcp6-client.h" static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link); @@ -247,42 +246,3 @@ int dhcp6_configure(Link *link, bool inf_req) { link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; } - -int dhcp6_prefix_expired(Link *link) { - int r; - sd_dhcp6_lease *lease; - struct in6_addr *expired_prefix, ip6_addr; - uint8_t expired_prefixlen; - uint32_t lifetime_preferred, lifetime_valid; - - r = sd_ndisc_get_expired_prefix(link->ndisc_router_discovery, - &expired_prefix, &expired_prefixlen); - if (r < 0) - return r; - - r = sd_dhcp6_client_get_lease(link->dhcp6_client, &lease); - if (r < 0) - return r; - - log_link_info(link, "IPv6 prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d expired", - SD_NDISC_ADDRESS_FORMAT_VAL(*expired_prefix), - expired_prefixlen); - - sd_dhcp6_lease_reset_address_iter(lease); - - while (sd_dhcp6_lease_get_address(lease, &ip6_addr, - &lifetime_preferred, - &lifetime_valid) >= 0) { - - r = sd_ndisc_prefix_match(expired_prefix, expired_prefixlen, - &ip6_addr); - if (r < 0) - continue; - - log_link_info(link, "IPv6 prefix length updated "SD_NDISC_ADDRESS_FORMAT_STR"/%d", SD_NDISC_ADDRESS_FORMAT_VAL(ip6_addr), 128); - - dhcp6_address_change(link, &ip6_addr, lifetime_preferred, lifetime_valid); - } - - return 0; -} diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 6bc88157cf..5c92df4ca8 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -146,7 +146,6 @@ int link_set_timezone(Link *link, const char *timezone); int ipv4ll_configure(Link *link); int dhcp4_configure(Link *link); int dhcp6_configure(Link *link, bool information_request); -int dhcp6_prefix_expired(Link *link); int ndisc_configure(Link *link); bool link_lldp_enabled(Link *link); diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 1721cb36b6..ab4bb51280 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -38,6 +38,7 @@ static void ndisc_router_handler(sd_ndisc *nd, int event, void *userdata) { switch(event) { case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE: + case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED: return; case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER: @@ -50,12 +51,6 @@ static void ndisc_router_handler(sd_ndisc *nd, int event, void *userdata) { break; - case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED: - if (!link->rtnl_extended_attrs) - dhcp6_prefix_expired(link); - - break; - default: if (event < 0) log_link_warning_errno(link, event, "IPv6 Neighbor Discover error: %m"); -- cgit v1.2.3-54-g00ecf From c93578f54b02a162d48590b7b61191cae96e9c2b Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 18 Oct 2015 17:13:03 +0200 Subject: sd-ndisc: clean up state enum There is no need to assign valuse to the states. Also add _INVALID and _MAX, even though these are not used, it keeps it consistent. --- src/libsystemd-network/sd-ndisc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 92c872e166..7921eb71a2 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -35,9 +35,11 @@ #define NDISC_MAX_ROUTER_SOLICITATIONS 3 enum NDiscState { - NDISC_STATE_IDLE = 0, - NDISC_STATE_SOLICITATION_SENT = 10, - NDISC_STATE_ADVERTISMENT_LISTEN = 11, + NDISC_STATE_IDLE, + NDISC_STATE_SOLICITATION_SENT, + NDISC_STATE_ADVERTISMENT_LISTEN, + _NDISC_STATE_MAX, + _NDISC_STATE_INVALID = -1, }; #define IP6_MIN_MTU (unsigned)1280 -- cgit v1.2.3-54-g00ecf From 77b05fa9a7120f2acb94221ae42bc8bb681df347 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 18 Oct 2015 17:19:29 +0200 Subject: sd-ndisc: don't inform the caller of expired prefixes The caller should push any lifetime information into the kernel and let the kernel handle prefix expiration. --- src/libsystemd-network/sd-ndisc.c | 20 -------------------- src/network/networkd-ndisc.c | 1 - src/systemd/sd-ndisc.h | 3 --- 3 files changed, 24 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 7921eb71a2..ceabd654ef 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -67,7 +67,6 @@ struct sd_ndisc { int index; struct ether_addr mac_addr; uint32_t mtu; - NDiscPrefix *expired_prefix; LIST_HEAD(NDiscPrefix, prefixes); int fd; sd_event_source *recv; @@ -283,11 +282,6 @@ static int ndisc_prefix_timeout(sd_event_source *s, uint64_t usec, LIST_REMOVE(prefixes, nd->prefixes, prefix); - nd->expired_prefix = prefix; - ndisc_notify(nd, - SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED); - nd->expired_prefix = NULL; - prefix = ndisc_prefix_unref(prefix); break; @@ -390,20 +384,6 @@ int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, return 0; } -int sd_ndisc_get_expired_prefix(sd_ndisc *nd, struct in6_addr **addr, uint8_t *prefixlen) { - assert_return(nd, -EINVAL); - assert_return(addr, -EINVAL); - assert_return(prefixlen, -EINVAL); - - if (!nd->expired_prefix) - return -EADDRNOTAVAIL; - - *addr = &nd->expired_prefix->addr; - *prefixlen = nd->expired_prefix->len; - - return 0; -} - static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, const struct nd_opt_prefix_info *prefix_opt) { int r; diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index ab4bb51280..637c29973e 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -38,7 +38,6 @@ static void ndisc_router_handler(sd_ndisc *nd, int event, void *userdata) { switch(event) { case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE: - case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED: return; case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER: diff --git a/src/systemd/sd-ndisc.h b/src/systemd/sd-ndisc.h index 8cee7343b5..963e161e6a 100644 --- a/src/systemd/sd-ndisc.h +++ b/src/systemd/sd-ndisc.h @@ -31,7 +31,6 @@ enum { SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT = 1, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER = 2, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED = 3, - SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED = 4, }; typedef struct sd_ndisc sd_ndisc; @@ -58,8 +57,6 @@ int sd_ndisc_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu); int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, uint8_t *prefixlen); -int sd_ndisc_get_expired_prefix(sd_ndisc *nd, struct in6_addr **addr, - uint8_t *prefixlen); int sd_ndisc_stop(sd_ndisc *nd); int sd_ndisc_router_discovery_start(sd_ndisc *nd); -- cgit v1.2.3-54-g00ecf From 272f5cd9b7137e7b82b8b2d33e268b8264d25b5b Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 18 Oct 2015 17:27:10 +0200 Subject: sd-ndisc: remove a prefix from the ndisc object when freeing it This follows the coding style, and allows some simplification to the rest of the code. --- src/libsystemd-network/sd-ndisc.c | 43 ++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index ceabd654ef..24280c1068 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -51,6 +51,8 @@ typedef struct NDiscPrefix NDiscPrefix; struct NDiscPrefix { unsigned n_ref; + sd_ndisc *nd; + LIST_FIELDS(NDiscPrefix, prefixes); uint8_t len; @@ -90,11 +92,16 @@ static NDiscPrefix *ndisc_prefix_unref(NDiscPrefix *prefix) { return NULL; prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid); + + if (prefix->nd) + LIST_REMOVE(prefixes, prefix->nd->prefixes, prefix); + free(prefix); + return NULL; } -static int ndisc_prefix_new(NDiscPrefix **ret) { +static int ndisc_prefix_new(sd_ndisc *nd, NDiscPrefix **ret) { _cleanup_free_ NDiscPrefix *prefix = NULL; assert(ret); @@ -105,6 +112,7 @@ static int ndisc_prefix_new(NDiscPrefix **ret) { prefix->n_ref = 1; LIST_INIT(prefixes, prefix); + prefix->nd = nd; *ret = prefix; prefix = NULL; @@ -217,11 +225,8 @@ sd_ndisc *sd_ndisc_unref(sd_ndisc *nd) { ndisc_init(nd); sd_ndisc_detach_event(nd); - LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { - LIST_REMOVE(prefixes, nd->prefixes, prefix); - + LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) prefix = ndisc_prefix_unref(prefix); - } free(nd); @@ -265,27 +270,15 @@ int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu) { return 0; } -static int ndisc_prefix_timeout(sd_event_source *s, uint64_t usec, - void *userdata) { - sd_ndisc *nd = userdata; - NDiscPrefix *prefix, *p; +static int ndisc_prefix_timeout(sd_event_source *s, uint64_t usec, void *userdata) { + NDiscPrefix *prefix = userdata; - assert(nd); - - LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { - if (prefix->timeout_valid != s) - continue; - - log_ndisc(nd, "Prefix expired "SD_NDISC_ADDRESS_FORMAT_STR"/%d", - SD_NDISC_ADDRESS_FORMAT_VAL(prefix->addr), - prefix->len); + assert(prefix); - LIST_REMOVE(prefixes, nd->prefixes, prefix); + log_ndisc(nd, "Prefix expired "SD_NDISC_ADDRESS_FORMAT_STR"/%d", + SD_NDISC_ADDRESS_FORMAT_VAL(prefix->addr), prefix->len); - prefix = ndisc_prefix_unref(prefix); - - break; - } + ndisc_prefix_unref(prefix); return 0; } @@ -306,7 +299,7 @@ static int ndisc_prefix_set_timeout(sd_ndisc *nd, r = sd_event_add_time(nd->event, &prefix->timeout_valid, clock_boottime_or_monotonic(), time_now + valid, - USEC_PER_SEC, ndisc_prefix_timeout, nd); + USEC_PER_SEC, ndisc_prefix_timeout, prefix); if (r < 0) goto error; @@ -413,7 +406,7 @@ static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, callback will be called immediately to clean up the prefix */ if (r == -EADDRNOTAVAIL) { - r = ndisc_prefix_new(&prefix); + r = ndisc_prefix_new(nd, &prefix); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf From f6e0ce66604a0b6cbd4319e10e63addd8a990722 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 18 Oct 2015 17:45:22 +0200 Subject: sd-ndisc: don't trigger timeout on prefix expiry The caller of the library is no longer notified, so triggering a timer just to clean up is not necessary. Instead check for and clean up invalid prefixes lazily. --- src/libsystemd-network/sd-ndisc.c | 98 +++++++++++++-------------------------- 1 file changed, 32 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 24280c1068..282dcbcc90 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -56,7 +56,7 @@ struct NDiscPrefix { LIST_FIELDS(NDiscPrefix, prefixes); uint8_t len; - sd_event_source *timeout_valid; + usec_t valid_until; struct in6_addr addr; }; @@ -91,8 +91,6 @@ static NDiscPrefix *ndisc_prefix_unref(NDiscPrefix *prefix) { if (prefix->n_ref > 0) return NULL; - prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid); - if (prefix->nd) LIST_REMOVE(prefixes, prefix->nd->prefixes, prefix); @@ -270,55 +268,6 @@ int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu) { return 0; } -static int ndisc_prefix_timeout(sd_event_source *s, uint64_t usec, void *userdata) { - NDiscPrefix *prefix = userdata; - - assert(prefix); - - log_ndisc(nd, "Prefix expired "SD_NDISC_ADDRESS_FORMAT_STR"/%d", - SD_NDISC_ADDRESS_FORMAT_VAL(prefix->addr), prefix->len); - - ndisc_prefix_unref(prefix); - - return 0; -} - -static int ndisc_prefix_set_timeout(sd_ndisc *nd, - NDiscPrefix *prefix, - usec_t valid) { - usec_t time_now; - int r; - - assert_return(prefix, -EINVAL); - - r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); - if (r < 0) - return r; - - prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid); - - r = sd_event_add_time(nd->event, &prefix->timeout_valid, - clock_boottime_or_monotonic(), time_now + valid, - USEC_PER_SEC, ndisc_prefix_timeout, prefix); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(prefix->timeout_valid, - nd->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(prefix->timeout_valid, - "ndisc-prefix-timeout"); - -error: - if (r < 0) - prefix->timeout_valid = - sd_event_source_unref(prefix->timeout_valid); - - return r; -} - static int prefix_match(const struct in6_addr *prefix, uint8_t prefixlen, const struct in6_addr *addr, uint8_t addr_prefixlen) { @@ -339,11 +288,25 @@ static int prefix_match(const struct in6_addr *prefix, uint8_t prefixlen, return 0; } -static int ndisc_prefix_match(NDiscPrefix *head, const struct in6_addr *addr, - uint8_t addr_len, NDiscPrefix **result) { - NDiscPrefix *prefix; +static int ndisc_prefix_match(sd_ndisc *nd, const struct in6_addr *addr, + uint8_t addr_len, NDiscPrefix **result) { + NDiscPrefix *prefix, *p; + usec_t time_now; + int r; + + assert(nd); + + r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) + return r; + + LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { + if (prefix->valid_until < time_now) { + prefix = ndisc_prefix_unref(prefix); + + continue; + } - LIST_FOREACH(prefixes, prefix, head) { if (prefix_match(&prefix->addr, prefix->len, addr, addr_len) >= 0) { *result = prefix; return 0; @@ -367,8 +330,7 @@ int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, assert_return(addr, -EINVAL); assert_return(prefixlen, -EINVAL); - r = ndisc_prefix_match(nd->prefixes, addr, - sizeof(addr->s6_addr) * 8, &prefix); + r = ndisc_prefix_match(nd, addr, sizeof(addr->s6_addr) * 8, &prefix); if (r < 0) return r; @@ -378,14 +340,15 @@ int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, } static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, - const struct nd_opt_prefix_info *prefix_opt) { - int r; + const struct nd_opt_prefix_info *prefix_opt) { NDiscPrefix *prefix; uint32_t lifetime; + usec_t time_now; char time_string[FORMAT_TIMESPAN_MAX]; + int r; - assert_return(nd, -EINVAL); - assert_return(prefix_opt, -EINVAL); + assert(nd); + assert(prefix_opt); if (len < prefix_opt->nd_opt_pi_len) return -ENOMSG; @@ -395,9 +358,8 @@ static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, lifetime = be32toh(prefix_opt->nd_opt_pi_valid_time); - r = ndisc_prefix_match(nd->prefixes, - &prefix_opt->nd_opt_pi_prefix, - prefix_opt->nd_opt_pi_prefix_len, &prefix); + r = ndisc_prefix_match(nd, &prefix_opt->nd_opt_pi_prefix, + prefix_opt->nd_opt_pi_prefix_len, &prefix); if (r < 0 && r != -EADDRNOTAVAIL) return r; @@ -442,7 +404,11 @@ static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime * USEC_PER_SEC, USEC_PER_SEC)); } - r = ndisc_prefix_set_timeout(nd, prefix, lifetime * USEC_PER_SEC); + r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) + return r; + + prefix->valid_until = time_now + lifetime * USEC_PER_SEC; return r; } -- cgit v1.2.3-54-g00ecf From f46fc04fac78e7067bb8b65109eed8d245dff0c3 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 19 Oct 2015 15:04:22 +0200 Subject: sd-ndisc: drop sd_ndisc_prefix_match() This is no longer used. --- src/libsystemd-network/sd-ndisc.c | 7 +------ src/systemd/sd-ndisc.h | 5 +---- 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 282dcbcc90..2df952e04c 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -316,13 +316,8 @@ static int ndisc_prefix_match(sd_ndisc *nd, const struct in6_addr *addr, return -EADDRNOTAVAIL; } -int sd_ndisc_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, - struct in6_addr *addr) { - return prefix_match(prefix, prefixlen, addr, sizeof(addr->s6_addr) * 8); -} - int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, - uint8_t *prefixlen) { + uint8_t *prefixlen) { int r; NDiscPrefix *prefix; diff --git a/src/systemd/sd-ndisc.h b/src/systemd/sd-ndisc.h index 963e161e6a..85152b32a6 100644 --- a/src/systemd/sd-ndisc.h +++ b/src/systemd/sd-ndisc.h @@ -51,12 +51,9 @@ sd_ndisc *sd_ndisc_ref(sd_ndisc *nd); sd_ndisc *sd_ndisc_unref(sd_ndisc *nd); int sd_ndisc_new(sd_ndisc **ret); -int sd_ndisc_prefix_match(struct in6_addr *prefix, uint8_t prefixlen, - struct in6_addr *addr); - int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu); int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, - uint8_t *prefixlen); + uint8_t *prefixlen); int sd_ndisc_stop(sd_ndisc *nd); int sd_ndisc_router_discovery_start(sd_ndisc *nd); -- cgit v1.2.3-54-g00ecf From 4e5ca364f4f8dadb90ec7cdb7db160dbd3b30966 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Wed, 21 Oct 2015 02:14:24 +0200 Subject: sd-ndisc: drop sd_ndisc_get_prefixlen() This is unused, and in the future we will pass prefixes and prefixlengths directly to the callbacks when needed rather than having to search for them. --- src/libsystemd-network/sd-ndisc.c | 18 ---- src/libsystemd-network/test-ndisc-rs.c | 186 --------------------------------- src/systemd/sd-ndisc.h | 2 - 3 files changed, 206 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 2df952e04c..fd512b5ce4 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -316,24 +316,6 @@ static int ndisc_prefix_match(sd_ndisc *nd, const struct in6_addr *addr, return -EADDRNOTAVAIL; } -int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, - uint8_t *prefixlen) { - int r; - NDiscPrefix *prefix; - - assert_return(nd, -EINVAL); - assert_return(addr, -EINVAL); - assert_return(prefixlen, -EINVAL); - - r = ndisc_prefix_match(nd, addr, sizeof(addr->s6_addr) * 8, &prefix); - if (r < 0) - return r; - - *prefixlen = prefix->len; - - return 0; -} - static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len, const struct nd_opt_prefix_info *prefix_opt) { NDiscPrefix *prefix; diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c index 0bb488cd91..765198e46c 100644 --- a/src/libsystemd-network/test-ndisc-rs.c +++ b/src/libsystemd-network/test-ndisc-rs.c @@ -53,191 +53,6 @@ int icmp6_bind_router_solicitation(int index) { return test_fd[0]; } -static int send_ra_short_prefix(uint8_t flags) { - uint8_t advertisement[] = { - 0x86, 0x00, 0xbe, 0xd7, 0x40, 0xc0, 0x00, 0xb4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x03, 0x04, 0x34, 0xc0, 0x00, 0x00, 0x01, 0xf4, - 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == - sizeof(advertisement)); - - return 0; -} - -static void test_short_prefix_cb(sd_ndisc *nd, int event, void *userdata) { - sd_event *e = userdata; - struct { - struct in6_addr addr; - uint8_t prefixlen; - bool success; - } addrs[] = { - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 52, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 64, false }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 60, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 64, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xed, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }, - 52, true }, - }; - uint8_t prefixlen; - unsigned int i; - - for (i = 0; i < ELEMENTSOF(addrs); i++) { - printf(" %s prefix %02x%02x:%02x%02x:%02x%02x:%02x%02x", - __FUNCTION__, - addrs[i].addr.s6_addr[0], addrs[i].addr.s6_addr[1], - addrs[i].addr.s6_addr[2], addrs[i].addr.s6_addr[3], - addrs[i].addr.s6_addr[4], addrs[i].addr.s6_addr[5], - addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]); - - if (addrs[i].success) { - assert_se(sd_ndisc_get_prefixlen(nd, &addrs[i].addr, - &prefixlen) >= 0); - assert_se(addrs[i].prefixlen == prefixlen); - printf("/%d onlink\n", prefixlen); - } else { - assert_se(sd_ndisc_get_prefixlen(nd, &addrs[i].addr, - &prefixlen) == -EADDRNOTAVAIL); - printf("/128 offlink\n"); - } - } - - sd_event_exit(e, 0); -} - -static int send_ra_prefixes(uint8_t flags) { - uint8_t advertisement[] = { - 0x86, 0x00, 0xbe, 0xd7, 0x40, 0xc0, 0x00, 0xb4, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x3f, 0xc0, 0x00, 0x00, 0x01, 0xf4, - 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x40, 0x00, 0x00, 0x00, 0x02, 0x58, - 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x3c, 0x80, 0x00, 0x00, 0x03, 0x84, - 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x03, 0x84, - 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, - 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53 - }; - - assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == - sizeof(advertisement)); - - return 0; -} - -static void test_prefixes_cb(sd_ndisc *nd, int event, void *userdata) { - sd_event *e = userdata; - struct { - struct in6_addr addr; - uint8_t prefixlen; - bool success; - } addrs[] = { - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 63, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 64, false }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 60, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, - 64, true }, - { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xed, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }, - 63, false }, - }; - uint8_t prefixlen; - unsigned int i; - - for (i = 0; i < ELEMENTSOF(addrs); i++) { - printf(" %s prefix %02x%02x:%02x%02x:%02x%02x:%02x%02x", - __FUNCTION__, - addrs[i].addr.s6_addr[0], addrs[i].addr.s6_addr[1], - addrs[i].addr.s6_addr[2], addrs[i].addr.s6_addr[3], - addrs[i].addr.s6_addr[4], addrs[i].addr.s6_addr[5], - addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]); - - if (addrs[i].success) { - assert_se(sd_ndisc_get_prefixlen(nd, &addrs[i].addr, - &prefixlen) >= 0); - assert_se(addrs[i].prefixlen == prefixlen); - printf("/%d onlink\n", prefixlen); - } else { - assert_se(sd_ndisc_get_prefixlen(nd, &addrs[i].addr, - &prefixlen) == -EADDRNOTAVAIL); - printf("/128 offlink\n"); - } - } - - send_ra_function = send_ra_short_prefix; - assert_se(sd_ndisc_set_callback(nd, test_short_prefix_cb, e) >= 0); - assert_se(sd_ndisc_stop(nd) >= 0); - assert_se(sd_ndisc_router_discovery_start(nd) >= 0); -} - -static void test_prefixes(void) { - sd_event *e; - sd_ndisc *nd; - - if (verbose) - printf("* %s\n", __FUNCTION__); - - send_ra_function = send_ra_prefixes; - - assert_se(sd_event_new(&e) >= 0); - - assert_se(sd_ndisc_new(&nd) >= 0); - assert_se(nd); - - assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0); - - assert_se(sd_ndisc_set_index(nd, 42) >= 0); - assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0); - assert_se(sd_ndisc_set_callback(nd, test_prefixes_cb, e) >= 0); - - assert_se(sd_ndisc_router_discovery_start(nd) >= 0); - - sd_event_loop(e); - - nd = sd_ndisc_unref(nd); - assert_se(!nd); - - close(test_fd[1]); - - sd_event_unref(e); -} - static int send_ra(uint8_t flags) { uint8_t advertisement[] = { 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4, @@ -351,7 +166,6 @@ int main(int argc, char *argv[]) { log_open(); test_rs(); - test_prefixes(); return 0; } diff --git a/src/systemd/sd-ndisc.h b/src/systemd/sd-ndisc.h index 85152b32a6..83575c6908 100644 --- a/src/systemd/sd-ndisc.h +++ b/src/systemd/sd-ndisc.h @@ -52,8 +52,6 @@ sd_ndisc *sd_ndisc_unref(sd_ndisc *nd); int sd_ndisc_new(sd_ndisc **ret); int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu); -int sd_ndisc_get_prefixlen(sd_ndisc *nd, const struct in6_addr *addr, - uint8_t *prefixlen); int sd_ndisc_stop(sd_ndisc *nd); int sd_ndisc_router_discovery_start(sd_ndisc *nd); -- cgit v1.2.3-54-g00ecf From cbe91b3cba3298866f51abfa598c5751e90fd390 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Thu, 22 Oct 2015 17:34:58 +0200 Subject: sd-ndisc: reduce callbacks Only callback on error when the statemachine is in a truly broken state. This is now only the case when we fail to rearm a timer. --- src/libsystemd-network/sd-ndisc.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index fd512b5ce4..a361662072 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -540,11 +540,7 @@ static int ndisc_router_solicitation_timeout(sd_event_source *s, uint64_t usec, nd->nd_sent++; - r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); - if (r < 0) { - ndisc_notify(nd, r); - return 0; - } + assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0); next_timeout = time_now + NDISC_ROUTER_SOLICITATION_INTERVAL; @@ -556,18 +552,13 @@ 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); - if (r < 0) { - ndisc_notify(nd, r); + r = sd_event_source_set_priority(nd->timeout, nd->event_priority); + if (r < 0) return 0; - } r = sd_event_source_set_description(nd->timeout, "ndisc-timeout"); - if (r < 0) { - ndisc_notify(nd, r); + if (r < 0) return 0; - } } return 0; -- cgit v1.2.3-54-g00ecf