mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
sd-lldp: take triple timestamp when reading LLDP packets
It's a good idea to store away the recption time of LLDP packets in the neighbor object, simply because the LLDP data only has a validity of a certain amount of time. Hence, let's record the timestamp when we receive the datagram and expose an API for it. Also, automatically expire LLDP neighbors based on this new timestamp.
This commit is contained in:
parent
e475d10c1b
commit
16fed825d6
@ -360,9 +360,16 @@ end_marker:
|
||||
void lldp_neighbor_start_ttl(sd_lldp_neighbor *n) {
|
||||
assert(n);
|
||||
|
||||
if (n->ttl > 0)
|
||||
n->until = usec_add(now(clock_boottime_or_monotonic()), n->ttl * USEC_PER_SEC);
|
||||
else
|
||||
if (n->ttl > 0) {
|
||||
usec_t base;
|
||||
|
||||
/* Use the packet's timestamp if there is one known */
|
||||
base = triple_timestamp_by_clock(&n->timestamp, clock_boottime_or_monotonic());
|
||||
if (base <= 0 || base == USEC_INFINITY)
|
||||
base = now(clock_boottime_or_monotonic()); /* Otherwise, take the current time */
|
||||
|
||||
n->until = usec_add(base, n->ttl * USEC_PER_SEC);
|
||||
} else
|
||||
n->until = 0;
|
||||
|
||||
if (n->lldp)
|
||||
@ -792,3 +799,16 @@ _public_ int sd_lldp_neighbor_tlv_get_raw(sd_lldp_neighbor *n, const void **ret,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret) {
|
||||
assert_return(n, -EINVAL);
|
||||
assert_return(TRIPLE_TIMESTAMP_HAS_CLOCK(clock), -EOPNOTSUPP);
|
||||
assert_return(clock_supported(clock), -EOPNOTSUPP);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if (!triple_timestamp_is_set(&n->timestamp))
|
||||
return -ENODATA;
|
||||
|
||||
*ret = triple_timestamp_by_clock(&n->timestamp, clock);
|
||||
return 0;
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ struct sd_lldp_neighbor {
|
||||
sd_lldp *lldp;
|
||||
unsigned n_ref;
|
||||
|
||||
triple_timestamp timestamp;
|
||||
|
||||
usec_t until;
|
||||
unsigned prioq_idx;
|
||||
|
||||
|
@ -138,6 +138,7 @@ static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
|
||||
|
||||
if (lldp_neighbor_equal(n, old)) {
|
||||
/* Is this equal, then restart the TTL counter, but don't do anyting else. */
|
||||
old->timestamp = n->timestamp;
|
||||
lldp_start_timer(lldp, old);
|
||||
lldp_callback(lldp, SD_LLDP_EVENT_REFRESHED, old);
|
||||
return 0;
|
||||
@ -202,6 +203,7 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v
|
||||
_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);
|
||||
@ -223,6 +225,12 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,7 @@ sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n);
|
||||
/* Access to LLDP frame metadata */
|
||||
int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address);
|
||||
int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address);
|
||||
int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret);
|
||||
int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size);
|
||||
|
||||
/* High-level, direct, parsed out field access. These fields exist at most once, hence may be queried directly. */
|
||||
|
Loading…
Reference in New Issue
Block a user