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(), &current) >= 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;
}
Example #2
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;
}
Example #6
0
inline s64 random_i64() { return s64(random_u64()); }