示例#1
0
static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
        _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
        ssize_t space, length;
        sd_lldp *lldp = userdata;

        assert(fd >= 0);
        assert(lldp);

        space = next_datagram_size_fd(fd);
        if (space < 0)
                return log_lldp_errno(space, "Failed to determine datagram size to read: %m");

        n = lldp_neighbor_new(space);
        if (!n)
                return -ENOMEM;

        length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT);
        if (length < 0)
                return log_lldp_errno(errno, "Failed to read LLDP datagram: %m");

        if ((size_t) length != n->raw_size) {
                log_lldp("Packet size mismatch.");
                return -EINVAL;
        }

        return lldp_handle_datagram(lldp, n);
}
示例#2
0
_public_ int sd_lldp_start(sd_lldp *lldp) {
        int r;

        assert_return(lldp, -EINVAL);
        assert_return(lldp->event, -EINVAL);
        assert_return(lldp->ifindex > 0, -EINVAL);

        if (lldp->fd >= 0)
                return 0;

        assert(!lldp->io_event_source);

        lldp->fd = lldp_network_bind_raw_socket(lldp->ifindex);
        if (lldp->fd < 0)
                return lldp->fd;

        r = sd_event_add_io(lldp->event, &lldp->io_event_source, lldp->fd, EPOLLIN, lldp_receive_datagram, lldp);
        if (r < 0)
                goto fail;

        r = sd_event_source_set_priority(lldp->io_event_source, lldp->event_priority);
        if (r < 0)
                goto fail;

        (void) sd_event_source_set_description(lldp->io_event_source, "lldp-io");

        log_lldp("Started LLDP client");
        return 1;

fail:
        lldp_reset(lldp);
        return r;
}
示例#3
0
static void lldp_callback(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n) {
        assert(lldp);

        log_lldp("Invoking callback for '%c'.", event);

        if (!lldp->callback)
                return;

        lldp->callback(lldp, event, n, lldp->userdata);
}
示例#4
0
_public_ int sd_lldp_stop(sd_lldp *lldp) {
        assert_return(lldp, -EINVAL);

        if (lldp->fd < 0)
                return 0;

        log_lldp("Stopping LLDP client");

        lldp_reset(lldp);
        lldp_flush_neighbors(lldp);

        return 1;
}
示例#5
0
static int lldp_handle_datagram(sd_lldp *lldp, sd_lldp_neighbor *n) {
        int r;

        assert(lldp);
        assert(n);

        r = lldp_neighbor_parse(n);
        if (r == -EBADMSG) /* Ignore bad messages */
                return 0;
        if (r < 0)
                return r;

        r = lldp_add_neighbor(lldp, n);
        if (r < 0) {
                log_lldp_errno(r, "Failed to add datagram. Ignoring.");
                return 0;
        }

        log_lldp("Successfully processed LLDP datagram.");
        return 0;
}
示例#6
0
static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
        _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
        ssize_t space, length;
        sd_lldp *lldp = userdata;
        struct timespec ts;

        assert(fd >= 0);
        assert(lldp);

        space = next_datagram_size_fd(fd);
        if (space < 0)
                return log_lldp_errno(space, "Failed to determine datagram size to read: %m");

        n = lldp_neighbor_new(space);
        if (!n)
                return -ENOMEM;

        length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT);
        if (length < 0) {
                if (errno == EAGAIN || errno == EINTR)
                        return 0;

                return log_lldp_errno(errno, "Failed to read LLDP datagram: %m");
        }

        if ((size_t) length != n->raw_size) {
                log_lldp("Packet size mismatch.");
                return -EINVAL;
        }

        /* Try to get the timestamp of this packet if it is known */
        if (ioctl(fd, SIOCGSTAMPNS, &ts) >= 0)
                triple_timestamp_from_realtime(&n->timestamp, timespec_load(&ts));
        else
                triple_timestamp_get(&n->timestamp);

        return lldp_handle_datagram(lldp, n);
}