diff options
Diffstat (limited to 'src/libsystemd-network/sd-icmp6-nd.c')
-rw-r--r-- | src/libsystemd-network/sd-icmp6-nd.c | 95 |
1 files changed, 51 insertions, 44 deletions
diff --git a/src/libsystemd-network/sd-icmp6-nd.c b/src/libsystemd-network/sd-icmp6-nd.c index 2f867e8562..bedcac8d9e 100644 --- a/src/libsystemd-network/sd-icmp6-nd.c +++ b/src/libsystemd-network/sd-icmp6-nd.c @@ -25,7 +25,6 @@ #include <sys/ioctl.h> #include "socket-util.h" -#include "refcnt.h" #include "async.h" #include "dhcp6-internal.h" @@ -47,7 +46,7 @@ enum icmp6_nd_state { typedef struct ICMP6Prefix ICMP6Prefix; struct ICMP6Prefix { - RefCount n_ref; + unsigned n_ref; LIST_FIELDS(ICMP6Prefix, prefixes); @@ -57,7 +56,7 @@ struct ICMP6Prefix { }; struct sd_icmp6_nd { - RefCount n_ref; + unsigned n_ref; enum icmp6_nd_state state; sd_event *event; @@ -78,13 +77,18 @@ struct sd_icmp6_nd { #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 && REFCNT_DEC(prefix->n_ref) <= 0) { - prefix->timeout_valid = - sd_event_source_unref(prefix->timeout_valid); - free(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; } @@ -97,7 +101,7 @@ static int icmp6_prefix_new(ICMP6Prefix **ret) { if (!prefix) return -ENOMEM; - prefix->n_ref = REFCNT_INIT; + prefix->n_ref = 1; LIST_INIT(prefixes, prefix); *ret = prefix; @@ -106,8 +110,7 @@ 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_icmp6_nd *nd, int event) { if (nd->callback) nd->callback(nd, event, nd->userdata); } @@ -177,9 +180,12 @@ sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd) { } sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd) { - assert (nd); - assert_se(REFCNT_INC(nd->n_ref) >= 2); + if (!nd) + return NULL; + + assert(nd->n_ref > 0); + nd->n_ref++; return nd; } @@ -195,21 +201,28 @@ static int icmp6_nd_init(sd_icmp6_nd *nd) { } sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) { - if (nd && REFCNT_DEC(nd->n_ref) == 0) { - ICMP6Prefix *prefix, *p; + ICMP6Prefix *prefix, *p; - icmp6_nd_init(nd); - sd_icmp6_nd_detach_event(nd); + if (!nd) + return NULL; - LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { - LIST_REMOVE(prefixes, nd->prefixes, prefix); + assert(nd->n_ref > 0); + nd->n_ref--; - prefix = icmp6_prefix_unref(prefix); - } + if (nd->n_ref > 0) + return NULL; + + icmp6_nd_init(nd); + sd_icmp6_nd_detach_event(nd); - free(nd); + LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { + LIST_REMOVE(prefixes, nd->prefixes, prefix); + + prefix = icmp6_prefix_unref(prefix); } + free(nd); + return NULL; } @@ -225,7 +238,7 @@ int sd_icmp6_nd_new(sd_icmp6_nd **ret) { if (!nd) return -ENOMEM; - nd->n_ref = REFCNT_INIT; + nd->n_ref = 1; nd->index = -1; nd->fd = -1; @@ -261,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_ADDRESS_FORMAT_STR"/%d", - SD_ICMP6_ADDRESS_FORMAT_VAL(prefix->addr), + 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, - ICMP6_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED); + SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED); nd->expired_prefix = NULL; prefix = icmp6_prefix_unref(prefix); @@ -376,9 +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_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); @@ -430,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_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", - SD_ICMP6_ADDRESS_FORMAT_VAL(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, 0)); @@ -452,8 +463,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_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s", - SD_ICMP6_ADDRESS_FORMAT_VAL(prefix->addr), + 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, 0)); @@ -525,14 +536,12 @@ static int icmp6_ra_parse(sd_icmp6_nd *nd, struct nd_router_advert *ra, return 0; } -static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, - uint32_t revents, void *userdata) -{ +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 = ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE; + int event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_NONE; assert(s); assert(nd); @@ -563,16 +572,16 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; if (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER ) - event = ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER; + event = SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER; if (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) - event = ICMP6_EVENT_ROUTER_ADVERTISMENT_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 != ICMP6_EVENT_ROUTER_ADVERTISMENT_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", @@ -586,9 +595,7 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, return 0; } -static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, - void *userdata) -{ +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 = { }; @@ -602,7 +609,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, ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT); + 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))) |