struct NDiscPrefix {
unsigned n_ref;
+ sd_ndisc *nd;
+
LIST_FIELDS(NDiscPrefix, prefixes);
uint8_t len;
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);
prefix->n_ref = 1;
LIST_INIT(prefixes, prefix);
+ prefix->nd = nd;
*ret = prefix;
prefix = NULL;
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);
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;
}
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;
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;