static int on_lldp_timer(sd_event_source *s, usec_t t, void *userdata) { Link *link = userdata; usec_t current, delay, next; int r; assert(s); assert(userdata); log_link_debug(link, "Sending LLDP packet..."); r = link_send_lldp(link); if (r < 0) log_link_debug_errno(link, r, "Failed to send LLDP packet, ignoring: %m"); if (link->lldp_tx_fast > 0) link->lldp_tx_fast--; assert_se(sd_event_now(sd_event_source_get_event(s), clock_boottime_or_monotonic(), ¤t) >= 0); delay = link->lldp_tx_fast > 0 ? LLDP_FAST_TX_USEC : LLDP_TX_INTERVAL_USEC; next = usec_add(usec_add(current, delay), (usec_t) random_u64() % LLDP_JITTER_USEC); r = sd_event_source_set_time(s, next); if (r < 0) return log_link_error_errno(link, r, "Failed to restart LLDP timer: %m"); r = sd_event_source_set_enabled(s, SD_EVENT_ONESHOT); if (r < 0) return log_link_error_errno(link, r, "Failed to enable LLDP timer: %m"); return 0; }
static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_usec) { _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL; usec_t next_timeout, time_now; int r; assert(acd); next_timeout = usec; if (random_usec > 0) next_timeout += (usec_t) random_u64() % random_usec; assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &time_now) >= 0); r = sd_event_add_time(acd->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, acd); if (r < 0) return r; r = sd_event_source_set_priority(timer, acd->event_priority); if (r < 0) return r; (void) sd_event_source_set_description(timer, "ipv4acd-timer"); sd_event_source_unref(acd->timer_event_source); acd->timer_event_source = timer; timer = NULL; return 0; }
static int pppoe_send(sd_pppoe *ppp, uint8_t code) { union sockaddr_union link = { .ll = { .sll_family = AF_PACKET, .sll_protocol = htons(ETH_P_PPP_DISC), .sll_halen = ETH_ALEN, }, }; _cleanup_free_ struct pppoe_hdr *packet = NULL; int r; assert(ppp); assert(ppp->fd != -1); assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE)); link.ll.sll_ifindex = ppp->ifindex; if (code == PADI_CODE) memset(&link.ll.sll_addr, 0xff, ETH_ALEN); else memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN); packet = malloc0(PPPOE_MAX_PACKET_SIZE); if (!packet) return -ENOMEM; packet->ver = 0x1; packet->type = 0x1; packet->code = code; if (code == PADT_CODE) packet->sid = ppp->session_id; /* Service-Name */ pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME, ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0); /* AC-Cookie */ if (code == PADR_CODE && ppp->tags.cookie) pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_AC_COOKIE, ppp->tags.cookie, ppp->tags.cookie_len); /* Host-Uniq */ if (code != PADT_CODE) { ppp->host_uniq = random_u64(); pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ, &ppp->host_uniq, sizeof(ppp->host_uniq)); } r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet), 0, &link.sa, sizeof(link.ll)); if (r < 0) return -errno; return 0; }
static void prefix_random(const char *name, char **ret) { uint64_t i, u; char *m = NULL; u = 1 + (random_u64() & 3); for (i = 0; i < u; i++) { _cleanup_free_ char *b = NULL; char *x; assert_se(asprintf(&b, "x%" PRIu64 "x", random_u64())); x = strjoin(b, ".", name); assert_se(x); free(m); m = x; } *ret = m; }
int link_lldp_emit_start(Link *link) { usec_t next; int r; assert(link); if (!link->network || link->network->lldp_emit == LLDP_EMIT_NO) { link_lldp_emit_stop(link); return 0; } /* Starts the LLDP transmission in "fast" mode. If it is already started, turns "fast" mode back on again. */ link->lldp_tx_fast = LLDP_TX_FAST_INIT; next = usec_add(usec_add(now(clock_boottime_or_monotonic()), LLDP_FAST_TX_USEC), (usec_t) random_u64() % LLDP_JITTER_USEC); if (link->lldp_emit_event_source) { usec_t old; /* Lower the timeout, maybe */ r = sd_event_source_get_time(link->lldp_emit_event_source, &old); if (r < 0) return r; if (old <= next) return 0; return sd_event_source_set_time(link->lldp_emit_event_source, next); } else { r = sd_event_add_time( link->manager->event, &link->lldp_emit_event_source, clock_boottime_or_monotonic(), next, 0, on_lldp_timer, link); if (r < 0) return r; (void) sd_event_source_set_description(link->lldp_emit_event_source, "lldp-tx"); } return 0; }
inline s64 random_i64() { return s64(random_u64()); }