Lines Matching defs:nd
63 sd_ndisc *nd;
106 if (prefix->nd)
107 LIST_REMOVE(prefixes, prefix->nd->prefixes, prefix);
114 static int ndisc_prefix_new(sd_ndisc *nd, NDiscPrefix **ret) {
125 prefix->nd = nd;
131 int sd_ndisc_set_callback(sd_ndisc *nd,
137 assert(nd);
139 nd->router_callback = router_callback;
140 nd->prefix_onlink_callback = prefix_onlink_callback;
141 nd->prefix_autonomous_callback = prefix_autonomous_callback;
142 nd->callback = callback;
143 nd->userdata = userdata;
148 int sd_ndisc_set_index(sd_ndisc *nd, int interface_index) {
149 assert(nd);
152 nd->index = interface_index;
157 int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr) {
158 assert(nd);
161 memcpy(&nd->mac_addr, mac_addr, sizeof(nd->mac_addr));
163 zero(nd->mac_addr);
169 int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int priority) {
172 assert_return(nd, -EINVAL);
173 assert_return(!nd->event, -EBUSY);
176 nd->event = sd_event_ref(event);
178 r = sd_event_default(&nd->event);
183 nd->event_priority = priority;
188 int sd_ndisc_detach_event(sd_ndisc *nd) {
189 assert_return(nd, -EINVAL);
191 nd->event = sd_event_unref(nd->event);
196 sd_event *sd_ndisc_get_event(sd_ndisc *nd) {
197 assert(nd);
199 return nd->event;
202 sd_ndisc *sd_ndisc_ref(sd_ndisc *nd) {
204 if (!nd)
207 assert(nd->n_ref > 0);
208 nd->n_ref++;
210 return nd;
213 static int ndisc_init(sd_ndisc *nd) {
214 assert(nd);
216 nd->recv = sd_event_source_unref(nd->recv);
217 nd->fd = asynchronous_close(nd->fd);
218 nd->timeout = sd_event_source_unref(nd->timeout);
223 sd_ndisc *sd_ndisc_unref(sd_ndisc *nd) {
226 if (!nd)
229 assert(nd->n_ref > 0);
230 nd->n_ref--;
232 if (nd->n_ref > 0)
235 ndisc_init(nd);
236 sd_ndisc_detach_event(nd);
238 LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes)
241 free(nd);
247 _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL;
251 nd = new0(sd_ndisc, 1);
252 if (!nd)
255 nd->n_ref = 1;
257 nd->index = -1;
258 nd->fd = -1;
260 LIST_HEAD_INIT(nd->prefixes);
262 *ret = nd;
263 nd = NULL;
268 int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu) {
269 assert_return(nd, -EINVAL);
272 if (nd->mtu == 0)
275 *mtu = nd->mtu;
300 static int ndisc_prefix_match(sd_ndisc *nd, const struct in6_addr *addr,
306 assert(nd);
308 r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now);
312 LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) {
327 static int ndisc_prefix_update(sd_ndisc *nd, ssize_t len,
335 assert(nd);
353 r = ndisc_prefix_match(nd, &prefix_opt->nd_opt_pi_prefix,
362 r = ndisc_prefix_new(nd, &prefix);
371 log_ndisc(nd, "New prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s",
376 LIST_PREPEND(prefixes, nd->prefixes, prefix);
384 log_ndisc(nd, "Prefix length mismatch %d/%d using %d",
392 log_ndisc(nd, "Update prefix "SD_NDISC_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s",
398 r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now);
404 if ((prefix_opt->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK) && nd->prefix_onlink_callback)
405 nd->prefix_onlink_callback(nd, &prefix->addr, prefix->len, prefix->valid_until, nd->userdata);
407 if ((prefix_opt->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO) && nd->prefix_autonomous_callback)
408 nd->prefix_autonomous_callback(nd, &prefix->addr, prefix->len, lifetime_preferred, lifetime_valid,
409 nd->userdata);
414 static int ndisc_ra_parse(sd_ndisc *nd, struct nd_router_advert *ra, ssize_t len) {
418 assert_return(nd, -EINVAL);
423 log_ndisc(nd, "Router Advertisement below minimum length");
445 if (mtu != nd->mtu) {
446 nd->mtu = MAX(mtu, IP6_MIN_MTU);
448 log_ndisc(nd, "Router Advertisement link MTU %d using %d",
449 mtu, nd->mtu);
457 ndisc_prefix_update(nd, len, opt_prefix);
469 log_ndisc(nd, "Router Advertisement contains %zd bytes of trailing garbage", len);
476 sd_ndisc *nd = userdata;
498 assert(nd);
499 assert(nd->event);
521 log_ndisc(nd, "Could not receive message from ICMPv6 socket: %m");
528 log_ndisc(nd, "Received invalid source address size from ICMPv6 socket: %zu bytes", (size_t)msg.msg_namelen);
543 log_ndisc(nd, "Received RA with invalid hop limit %d. Ignoring.", hops);
556 log_ndisc(nd, "Received RA from non-link-local address %s. Ignoring.", strna(addr));
566 nd->timeout = sd_event_source_unref(nd->timeout);
568 nd->state = NDISC_STATE_ADVERTISMENT_LISTEN;
584 log_ndisc(nd, "Received Router Advertisement: flags %s preference %s lifetime %u sec",
589 r = ndisc_ra_parse(nd, ra, len);
591 log_ndisc(nd, "Could not parse Router Advertisement: %s", strerror(-r));
595 if (nd->router_callback)
596 nd->router_callback(nd, stateful, gw, lifetime, pref, nd->userdata);
602 sd_ndisc *nd = userdata;
607 assert(nd);
608 assert(nd->event);
610 nd->timeout = sd_event_source_unref(nd->timeout);
612 if (nd->nd_sent >= NDISC_MAX_ROUTER_SOLICITATIONS) {
613 if (nd->callback)
614 nd->callback(nd, SD_NDISC_EVENT_TIMEOUT, nd->userdata);
615 nd->state = NDISC_STATE_ADVERTISMENT_LISTEN;
617 r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
619 log_ndisc(nd, "Error sending Router Solicitation");
621 nd->state = NDISC_STATE_SOLICITATION_SENT;
622 log_ndisc(nd, "Sent Router Solicitation");
625 nd->nd_sent++;
627 assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
631 r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(),
633 ndisc_router_solicitation_timeout, nd);
636 sd_ndisc_stop(nd);
640 r = sd_event_source_set_priority(nd->timeout, nd->event_priority);
644 r = sd_event_source_set_description(nd->timeout, "ndisc-timeout");
652 int sd_ndisc_stop(sd_ndisc *nd) {
653 assert_return(nd, -EINVAL);
654 assert_return(nd->event, -EINVAL);
658 ndisc_init(nd);
660 nd->state = NDISC_STATE_IDLE;
662 if (nd->callback)
663 nd->callback(nd, SD_NDISC_EVENT_STOP, nd->userdata);
668 int sd_ndisc_router_discovery_start(sd_ndisc *nd) {
671 assert(nd);
672 assert(nd->event);
674 if (nd->state != NDISC_STATE_IDLE)
677 if (nd->index < 1)
680 r = icmp6_bind_router_solicitation(nd->index);
684 nd->fd = r;
686 r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN,
687 ndisc_router_advertisment_recv, nd);
691 r = sd_event_source_set_priority(nd->recv, nd->event_priority);
695 r = sd_event_source_set_description(nd->recv, "ndisc-receive-message");
699 r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(),
700 0, 0, ndisc_router_solicitation_timeout, nd);
704 r = sd_event_source_set_priority(nd->timeout, nd->event_priority);
708 r = sd_event_source_set_description(nd->timeout, "ndisc-timeout");
711 ndisc_init(nd);