Changeset e2cd7d8


Ignore:
Timestamp:
11/04/15 17:19:19 (6 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
pfring
Children:
a21b45e
Parents:
06926f4
Message:

More pfring improvements

Only byteswap if the byte-ordering of the pfring header doesn't
match the byte ordering of the host looking at it. It's a bit of a pain,
but we were losing quite a bit of performance by always byteswapping to
a standard byte order upon reading the packet.

Turns out the pfring API has a get_selectable_fd function so our event
API doesn't need to poll if no packets are available.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_pfring.c

    r06926f4 re2cd7d8  
    145145};
    146146
     147#define PFRING_BYTEORDER_BIGENDIAN 0
     148#define PFRING_BYTEORDER_LITTLEENDIAN 1
     149
     150#if __BYTE_ORDER == __BIG_ENDIAN
     151#define PFRING_MY_BYTEORDER PFRING_BYTEORDER_BIGENDIAN
     152#else
     153#define PFRING_MY_BYTEORDER PFRING_BYTEORDER_LITTLEENDIAN
     154#endif
     155
    147156
    148157struct libtrace_pfring_header {
     158        uint8_t byteorder;
    149159        struct {
    150160                uint64_t tv_sec;
     
    380390static int pfring_get_capture_length(const libtrace_packet_t *packet) {
    381391        struct libtrace_pfring_header *phdr;
     392        uint32_t wlen, caplen;
    382393        phdr = (struct libtrace_pfring_header *)packet->header;
    383394
    384395        if (packet->payload == NULL)
    385396                return 0;
    386         if (ntohl(phdr->wlen) < ntohl(phdr->caplen))
    387                 return ntohl(phdr->wlen);
    388         return ntohl(phdr->caplen);
     397
     398        if (phdr->byteorder != PFRING_MY_BYTEORDER) {
     399                wlen = byteswap32(phdr->wlen);
     400                caplen = byteswap32(phdr->caplen);
     401        } else {
     402                wlen = phdr->wlen;
     403                caplen = phdr->caplen;
     404        }
     405
     406        if (wlen < caplen)
     407                return wlen;
     408        return caplen;
    389409       
    390410}
     
    393413        struct libtrace_pfring_header *phdr;
    394414        phdr = (struct libtrace_pfring_header *)packet->header;
    395         return ntohl(phdr->wlen);
     415        if (phdr->byteorder != PFRING_MY_BYTEORDER) {
     416                return byteswap32(phdr->wlen);
     417        }
     418        return phdr->wlen;
    396419}
    397420
     
    443466       
    444467        hdr = (struct libtrace_pfring_header *)packet->buffer;
    445         while (block) {
     468        do {
    446469                if ((rc = pfring_recv(stream->pd, (u_char **)&packet->payload,
    447470                        0, (struct pfring_pkthdr *)&local, 0)) == -1)
     
    457480                }
    458481                break;
    459         }
     482        } while (block);
    460483
    461484        if (rc == 0)
     
    465488         * export them over RT safely. Also deal with 32 vs 64 bit
    466489         * timevals! */
    467         hdr->ts.tv_sec = bswap_host_to_le64((uint64_t)local.ts.tv_sec);
    468         hdr->ts.tv_usec = bswap_host_to_le64((uint64_t)local.ts.tv_usec);
     490        //hdr->ts.tv_sec = bswap_host_to_le64((uint64_t)local.ts.tv_sec);
     491        //hdr->ts.tv_usec = bswap_host_to_le64((uint64_t)local.ts.tv_usec);
     492#if __BYTE_ORDER == __LITTLE_ENDIAN
     493        hdr->byteorder = PFRING_BYTEORDER_LITTLEENDIAN;
     494#else
     495        hdr->byteorder = PFRING_BYTEORDER_BIGENDIAN;
     496#endif
     497
     498/*
    469499        hdr->caplen = htonl(local.caplen);
    470500        hdr->wlen = htonl(local.wlen);
    471         hdr->ts.tv_sec = htonl(local.ts.tv_sec);
    472         hdr->ts.tv_usec = htonl(local.ts.tv_usec);
    473501        hdr->ext.ts_ns = bswap_host_to_le64(local.ext.ts_ns);
    474502        hdr->ext.flags = htonl(local.ext.flags);
     
    477505        hdr->ext.tx.bounce_iface = htonl(local.ext.tx.bounce_iface);
    478506        hdr->ext.parsed_hdr_len = htons(local.ext.parsed_hdr_len);
     507*/
     508        hdr->caplen = (local.caplen);
     509        hdr->wlen = (local.wlen);
     510        hdr->ext.ts_ns = (local.ext.ts_ns);
     511        hdr->ext.flags = (local.ext.flags);
     512        hdr->ext.if_index = (local.ext.if_index);
     513        hdr->ext.hash = (local.ext.hash);
     514        hdr->ext.tx.bounce_iface = (local.ext.tx.bounce_iface);
     515        hdr->ext.parsed_hdr_len = (local.ext.parsed_hdr_len);
    479516        hdr->ext.direction = local.ext.direction;
     517
    480518
    481519        /* I think we can ignore parsed as it will only be populated if
     
    527565
    528566        if (phdr->ext.ts_ns) {
    529                 uint64_t tns = bswap_le_to_host64(phdr->ext.ts_ns);
     567                uint64_t tns;
     568                if (phdr->byteorder == PFRING_MY_BYTEORDER)
     569                        tns = phdr->ext.ts_ns;
     570                else
     571                        tns = byteswap64(phdr->ext.ts_ns);
    530572
    531573                ts = ((tns / 1000000000) << 32);
    532574                ts += ((tns % 1000000000) << 32) / 1000000000;
    533575        } else {
    534                 ts = (((uint64_t)ntohl(phdr->ts.tv_sec)) << 32);
    535                 ts += (((uint64_t)(ntohl(phdr->ts.tv_usec)) << 32)/1000000);
     576                uint64_t sec, usec;
     577                if (phdr->byteorder == PFRING_MY_BYTEORDER) {
     578                        sec = (uint64_t)(phdr->ts.tv_sec);
     579                        usec = (uint64_t)(phdr->ts.tv_usec);
     580                } else {
     581                        sec = (uint64_t)byteswap32(phdr->ts.tv_sec);
     582                        usec = (uint64_t)byteswap32(phdr->ts.tv_usec);
     583                }
     584
     585                ts = (sec << 32);
     586                ts += ((usec << 32)/1000000);
    536587        }
    537588        return ts;
     
    550601
    551602        packet->capture_length = -1;
    552         phdr->caplen = htonl(size);
     603        if (phdr->byteorder != PFRING_MY_BYTEORDER) {
     604                phdr->caplen = byteswap32(size);
     605        } else {
     606                phdr->caplen = size;
     607        }
    553608        return trace_get_capture_length(packet);
    554609}
     
    601656                        event.type = TRACE_EVENT_TERMINATE;
    602657                } else {
    603                         event.type = TRACE_EVENT_SLEEP;
    604                         event.seconds = 0.0001;
     658                        event.type = TRACE_EVENT_IOWAIT;
     659                        event.fd = pfring_get_selectable_fd(FORMAT_DATA_FIRST->pd);
    605660                }
    606661        } else {
Note: See TracChangeset for help on using the changeset viewer.