Skip to content

Commit

Permalink
Add support for Arista 7280 timestamps
Browse files Browse the repository at this point in the history
  • Loading branch information
cardigliano committed Oct 17, 2024
1 parent 00c8e3e commit dc0ae0d
Show file tree
Hide file tree
Showing 34 changed files with 85 additions and 22 deletions.
8 changes: 7 additions & 1 deletion kernel/pf_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -2229,10 +2229,16 @@ static int parse_raw_pkt(u_char *data, u_int32_t data_len,

hdr->extended_hdr.parsed_pkt.eth_type = ntohs(eh->h_proto);

if (hdr->extended_hdr.parsed_pkt.eth_type == 0xd28b /* Arista 7280 */) {
struct ethhdr *dummy_eh = (struct ethhdr *) &data[sizeof(struct ethhdr)];
displ += 14;
hdr->extended_hdr.parsed_pkt.eth_type = ntohs(dummy_eh->h_proto);
}

if(hdr->extended_hdr.parsed_pkt.eth_type == ETH_P_8021Q /* 802.1q (VLAN) */) {
struct eth_vlan_hdr *vh;

hdr->extended_hdr.parsed_pkt.offset.vlan_offset = sizeof(struct ethhdr);
hdr->extended_hdr.parsed_pkt.offset.vlan_offset = displ;
if (data_len < hdr->extended_hdr.parsed_pkt.offset.vlan_offset + sizeof(struct eth_vlan_hdr)) return(0);
vh = (struct eth_vlan_hdr *) &data[hdr->extended_hdr.parsed_pkt.offset.vlan_offset];
hdr->extended_hdr.parsed_pkt.vlan_id = ntohs(vh->h_vlan_id) & VLAN_VID_MASK;
Expand Down
Binary file removed userland/lib/libs/libpfring_ft_aarch64_dbg.a
Binary file not shown.
Binary file removed userland/lib/libs/libpfring_ft_aarch64_dbg.so
Binary file not shown.
Binary file removed userland/lib/libs/libpfring_ft_aarch64_dbg_dl.a
Binary file not shown.
Binary file removed userland/lib/libs/libpfring_ft_aarch64_dbg_dl.so
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64.so
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64_core-avx2.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64_core-avx2_dl.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64_corei7-avx.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64_corei7-avx_dl.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64_corei7.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64_corei7_dl.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64_dl.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_ft_x86_64_dl.so
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_mlx_x86_64.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_mlx_x86_64.so
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_mlx_x86_64_core-avx2.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_mlx_x86_64_corei7-avx.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_mlx_x86_64_corei7.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_nt_x86_64.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_nt_x86_64.so
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_nt_x86_64_core-avx2.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_nt_x86_64_corei7-avx.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_nt_x86_64_corei7.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_zc_x86_64.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_zc_x86_64.so
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_zc_x86_64_core-avx2.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_zc_x86_64_corei7-avx.a
Binary file not shown.
Binary file modified userland/lib/libs/libpfring_zc_x86_64_corei7.a
Binary file not shown.
4 changes: 2 additions & 2 deletions userland/lib/pfring.h
Original file line number Diff line number Diff line change
Expand Up @@ -1322,7 +1322,7 @@ int pfring_handle_metawatch_hw_timestamp(u_char* buffer, struct pfring_pkthdr *h
* @param ticks_ts The ticks will be placed here.
* @return 0 on success, a negative number otherwise.
*/
int pfring_read_arista_keyframe(u_char *buffer, u_int32_t buffer_len, u_int64_t *ns_ts, u_int32_t *ticks_ts);
int pfring_read_arista_7150_keyframe(u_char *buffer, u_int32_t buffer_len, u_int64_t *ns_ts, u_int32_t *ticks_ts);

/**
* Reads a ARISTA-formatted timestamp from an incoming packet and puts it into the timestamp variable.
Expand All @@ -1331,7 +1331,7 @@ int pfring_read_arista_keyframe(u_char *buffer, u_int32_t buffer_len, u_int64_t
* @param ns_ts If found the hardware timestamp will be placed here
* @return The length of the ARISTA timestamp.
*/
int pfring_read_arista_hw_timestamp(u_char *buffer, u_int32_t buffer_len, u_int64_t *ns_ts);
int pfring_read_arista_7150_hw_timestamp(u_char *buffer, u_int32_t buffer_len, u_int64_t *ns_ts);

/**
* Strip a ARISTA-formatted timestamp from an incoming packet. If the timestamp is found, the
Expand Down
66 changes: 51 additions & 15 deletions userland/lib/pfring_hw_timestamp.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ int pfring_handle_ixia_hw_timestamp(u_char* buffer, struct pfring_pkthdr *hdr) {

/* ********************************* */

static u_int64_t last_arista_keyframe_nsec = 0;
static u_int32_t last_arista_keyframe_ticks = 0;
static u_int64_t last_arista_7150_keyframe_nsec = 0;
static u_int32_t last_arista_7150_keyframe_ticks = 0;

int pfring_read_arista_keyframe(u_char *buffer, u_int32_t buffer_len,
u_int64_t *ns_ts, u_int32_t *ticks_ts) {
int pfring_read_arista_7150_keyframe(u_char *buffer, u_int32_t buffer_len,
u_int64_t *ns_ts, u_int32_t *ticks_ts) {
struct arista_7150_keyframe_hw_ts *kf;
u_char bcmac[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
struct ethhdr *eh = (struct ethhdr*) buffer;
Expand Down Expand Up @@ -176,8 +176,8 @@ int pfring_read_arista_keyframe(u_char *buffer, u_int32_t buffer_len,
ns = be64toh(kf->utc_nsec);
t = ntohl(kf->asic_time.ticks);

last_arista_keyframe_nsec = ns;
last_arista_keyframe_ticks = t;
last_arista_7150_keyframe_nsec = ns;
last_arista_7150_keyframe_ticks = t;

if (unlikely(debug_ts))
printf("[ARISTA][Key-Frame] Ticks: %u UTC: %ju.%ju\n", t, ns/1000000000, ns%1000000000);
Expand All @@ -190,8 +190,8 @@ int pfring_read_arista_keyframe(u_char *buffer, u_int32_t buffer_len,

/* ********************************* */

int pfring_read_arista_hw_timestamp(u_char *buffer,
u_int32_t buffer_len, u_int64_t *ns_ts) {
int pfring_read_arista_7150_hw_timestamp(u_char *buffer,
u_int32_t buffer_len, u_int64_t *ns_ts) {
struct arista_7150_pkt_hw_ts *fcsts;
u_int32_t ticks;
double delta_ticks = 0, delta_nsec;
Expand All @@ -201,15 +201,15 @@ int pfring_read_arista_hw_timestamp(u_char *buffer,

ticks = ntohl(fcsts->asic.ticks);

if (last_arista_keyframe_ticks) {
if (ticks >= last_arista_keyframe_ticks)
delta_ticks = ticks - last_arista_keyframe_ticks;
if (last_arista_7150_keyframe_ticks) {
if (ticks >= last_arista_7150_keyframe_ticks)
delta_ticks = ticks - last_arista_7150_keyframe_ticks;
else
delta_ticks = 0x7FFFFFFF; /* 31 bit ticks ts */

delta_nsec = delta_ticks * 2.857; /* Clock rate is 350Mhz - Tick length 20.0/7.0 */

ns = last_arista_keyframe_nsec + delta_nsec;
ns = last_arista_7150_keyframe_nsec + delta_nsec;
}

if (unlikely(debug_ts))
Expand All @@ -222,19 +222,55 @@ int pfring_read_arista_hw_timestamp(u_char *buffer,

/* ********************************* */

int pfring_read_arista_7280_hw_timestamp(u_char *buffer, struct pfring_pkthdr *hdr) {
struct ethhdr *eh = (struct ethhdr *) buffer;
struct arista_7280_pkt_hw_ts *fcsts;
u_int16_t eth_type;
u_int64_t ns;
u_int32_t tv_sec, tv_nsec;

eth_type = ntohs(eh->h_proto);

if (eth_type != 0xd28b /* Arista 7280 */)
return -1;

fcsts = (struct arista_7280_pkt_hw_ts *) &buffer[sizeof(struct ethhdr)];

tv_sec = ntohl(fcsts->ts.tv_sec);
tv_nsec = ntohl(fcsts->ts.tv_nsec);

hdr->ts.tv_sec = tv_sec;
hdr->ts.tv_usec = tv_nsec/1000;

ns = (((u_int64_t) tv_sec) * 1000000000) + tv_nsec;
hdr->extended_hdr.timestamp_ns = ns;

if (unlikely(debug_ts))
printf("[ARISTA][Packet] UTC: %u.%uns\n", tv_sec, tv_nsec);

return 0;
}

/* ********************************* */

int pfring_handle_arista_hw_timestamp(u_char* buffer, struct pfring_pkthdr *hdr) {
u_int64_t ns;
u_int32_t ticks;

if(unlikely(hdr->caplen != hdr->len))
return -1; /* full packet only */

if (pfring_read_arista_keyframe(buffer, hdr->len, &ns, &ticks) == 0) {
if (pfring_read_arista_7280_hw_timestamp(buffer, hdr) == 0) {
/* This is a 7280 timestamped packet */
return 0;

} else if (pfring_read_arista_7150_keyframe(buffer, hdr->len, &ns, &ticks) == 0) {
/* This was a keyframe */
return 1; /* skip this packet */

} else {
/* This is a packet, reading the timestamp */
pfring_read_arista_hw_timestamp(buffer, hdr->len, &ns);
/* This is a 7150 timestamped packet, reading the timestamp */
pfring_read_arista_7150_hw_timestamp(buffer, hdr->len, &ns);
hdr->caplen = hdr->len = hdr->len - sizeof(struct arista_7150_pkt_hw_ts);
hdr->ts.tv_sec = ns/1000000000;
hdr->ts.tv_usec = (ns%1000000000)/1000;
Expand Down
12 changes: 12 additions & 0 deletions userland/lib/pfring_hw_timestamp.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ struct arista_7150_pkt_hw_ts {

/* *********************************************** */

struct arista_7280_pkt_hw_ts {
u_int16_t subtype;
u_int16_t version;
struct {
u_int32_t tv_sec;
u_int32_t tv_nsec;
} ts;
u_int16_t h_proto;
} __attribute__((__packed__));

/* *********************************************** */

#define VSS_APCON_TS_LEN sizeof(struct vss_apcon_hw_ts)

struct vss_apcon_hw_ts {
Expand Down
17 changes: 13 additions & 4 deletions userland/lib/pfring_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,11 @@ static int __pfring_parse_tunneled_pkt(u_char *data, struct pfring_pkthdr *hdr,
int pfring_parse_pkt(u_char *data, struct pfring_pkthdr *hdr, u_int8_t level /* L2..L4, 5 (tunnel) */,
u_int8_t add_timestamp /* 0,1 */, u_int8_t add_hash /* 0,1 */) {
struct ethhdr *eh = (struct ethhdr*) data;
u_int32_t data_len = hdr->caplen, displ = 0, ip_len;
u_int16_t analyzed = 0, fragment_offset = 0;
u_int32_t data_len = hdr->caplen;
u_int32_t displ = sizeof(struct ethhdr);
u_int32_t ip_len;
u_int16_t analyzed = 0;
u_int16_t fragment_offset = 0;

hdr->extended_hdr.parsed_pkt.tunnel.tunnel_id = NO_TUNNEL_ID;

Expand All @@ -248,13 +251,19 @@ int pfring_parse_pkt(u_char *data, struct pfring_pkthdr *hdr, u_int8_t level /*
hdr->extended_hdr.parsed_pkt.offset.vlan_offset = 0;
hdr->extended_hdr.parsed_pkt.vlan_id = 0; /* Any VLAN */

if (hdr->extended_hdr.parsed_pkt.eth_type == 0xd28b /* Arista 7280 */) {
struct ethhdr *dummy_eh = (struct ethhdr *) &data[sizeof(struct ethhdr)];
displ += 14;
hdr->extended_hdr.parsed_pkt.eth_type = ntohs(dummy_eh->h_proto);
}

#ifndef VLAN_VID_MASK
#define VLAN_VID_MASK 0x0fff
#endif

if (hdr->extended_hdr.parsed_pkt.eth_type == 0x8100 /* 802.1q (VLAN) */) {
struct eth_vlan_hdr *vh;
hdr->extended_hdr.parsed_pkt.offset.vlan_offset = sizeof(struct ethhdr);
hdr->extended_hdr.parsed_pkt.offset.vlan_offset = displ;
vh = (struct eth_vlan_hdr *) &data[hdr->extended_hdr.parsed_pkt.offset.vlan_offset];
hdr->extended_hdr.parsed_pkt.vlan_id = ntohs(vh->h_vlan_id) & VLAN_VID_MASK /* 0x0fff */;
hdr->extended_hdr.parsed_pkt.eth_type = ntohs(vh->h_proto);
Expand All @@ -274,7 +283,7 @@ int pfring_parse_pkt(u_char *data, struct pfring_pkthdr *hdr, u_int8_t level /*
}
}

hdr->extended_hdr.parsed_pkt.offset.l3_offset = hdr->extended_hdr.parsed_pkt.offset.eth_offset + displ + sizeof(struct ethhdr);
hdr->extended_hdr.parsed_pkt.offset.l3_offset = hdr->extended_hdr.parsed_pkt.offset.eth_offset + displ;

L3:

Expand Down

0 comments on commit dc0ae0d

Please sign in to comment.