Ilias Apalodimas(apalos) replied on github web page: platform/linux-generic/odp_packet_io.c line 137 @@ -89,6 +96,274 @@ int odp_pktio_init_local(void) return odp_pktio_ops_init_local(true); } +static int write_pcapng_hdr(pktio_entry_t *entry, int qidx) +{ + size_t len; + pcapng_section_hdr_block_t shb; + pcapng_interface_description_block_s idb; + int fd = entry->s.pcapng_info.pcapng_fd[qidx]; + + memset(&shb, 0, sizeof(shb)); + memset(&idb, 0, sizeof(idb)); + + shb.block_type = PCAPNG_BLOCK_TYPE_SHB; + shb.block_total_length = sizeof(shb); + shb.block_total_length2 = sizeof(shb); + shb.magic = PCAPNG_ENDIAN_MAGIC; + shb.version_major = 0x1; + shb.version_minor = 0x0; + shb.section_len = -1; + + len = write(fd, &shb, sizeof(shb)); + fsync(fd); + /* fail to write shb/idb means the pcapng is unreadable */ + if (!len) { + ODP_ERR("Failed to write pcapng section hdr\n"); + close(fd); + return -1; + } + + idb.block_type = PCAPNG_BLOCK_TYPE_IDB; + idb.block_total_length = sizeof(idb); + idb.block_total_length2 = sizeof(idb); + idb.linktype = 0x1; /* LINKTYPE_ETHERNET */ + idb.snaplen = 0x0; /* unlimited */ + len = write(fd, &idb, sizeof(idb)); + if (!len) { + ODP_ERR("Failed to write pcapng interface description\n"); + close(fd); + return -1; + } + fsync(fd); + + entry->s.pcapng_info.state[qidx] = PCAPNG_WR_HDR; + + return 0; +} + +static int write_pcapng_pkts(pktio_entry_t *entry, int qidx, + const odp_packet_t packets[], int num) +{ + int i = 0; + struct iovec packet_iov[3 * num]; + pcapng_enhanced_packet_block_t epb; + int iovcnt = 0; + ssize_t len = 0; + int fd = entry->s.pcapng_info.pcapng_fd[qidx]; + + for (i = 0; i < num; i++) { + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(packets[i]); + uint32_t pkt_len = _odp_packet_len(packets[i]); + char *buf = (char *)odp_packet_data(packets[i]); + + epb.block_type = PCAPNG_BLOCK_TYPE_EPB; + epb.block_total_length = sizeof(epb) + + ROUNDUP_ALIGN(pkt_len, PCAP_DATA_ALIGN) + + PCAP_DATA_ALIGN; + epb.interface_idx = 0; + epb.timestamp_high = (uint32_t)(pkt_hdr->timestamp.u64 >> 32); + epb.timestamp_low = (uint32_t)(pkt_hdr->timestamp.u64); + epb.captured_len = pkt_len; + epb.packet_len = pkt_len; + + /* epb */ + packet_iov[iovcnt].iov_base = &epb; + packet_iov[iovcnt].iov_len = sizeof(epb); + iovcnt++; + + /* data */ + packet_iov[iovcnt].iov_base = buf; + packet_iov[iovcnt].iov_len = + ROUNDUP_ALIGN(pkt_len, PCAP_DATA_ALIGN); + iovcnt++; + + /* trailing */ + packet_iov[iovcnt].iov_base = &epb.block_total_length; + packet_iov[iovcnt].iov_len = sizeof(uint32_t); + iovcnt++; + } + + /* we don't really care if we manage to write *all* data */ + len = writev(fd, packet_iov, iovcnt); + if (!len) + ODP_ERR("Failed to write pcapng data\n"); + fsync(fd); + + return len; +} + +static void pcapng_drain_fifo(int fd) +{ + char c; + ssize_t len; + + do { + len = read(fd, &c, sizeof(c)); + } while (len > 0 && len != -1); + ODP_DBG("Drain pcap fifo %d\n", len); +} + +static void *inotify_update(void *arg) +{ + pktio_entry_t *entry = (pktio_entry_t *)arg; + struct timeval time; + int ret; + ssize_t rdlen; + int i; + char buffer[INOTIFY_BUF_LEN]; + unsigned int max_queue = + MAX(entry->s.num_in_queue, entry->s.num_out_queue); + fd_set rfds; + + while (1) {
Comment: This essentially "reads" the inotify triggers for opening/closing the fifos and sets the appropriate variables for starting/stopping the pcapng dump on fifos. Will try to make it easier to read on the final PR > Ilias Apalodimas(apalos) wrote: > will fix >> Ilias Apalodimas(apalos) wrote: >> will fix >>> Ilias Apalodimas(apalos) wrote: >>> I'll check and update for the final PR >>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote: >>>> General cleanup should be part of `odp_term_global()` processing. >>>> Presumably `odp_pktio_close()` should also do cleanup for specific pktios. >>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote: >>>>> A few comments about what this routine is doing would be very helpful >>>>> here. This is not easy code to follow. Modularizing it into some `static >>>>> inline` helpers might also make the logic simpler. >>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote: >>>>>> This is redundant. If `len > 0` then by definition `len != -1`. >>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote: >>>>>>> This fails for multi-segment packets. `odp_packet_data(pkt)` is >>>>>>> shorthand for `odp_packet_offset(pkt, 0, NULL, NULL)` so you don't know >>>>>>> how long the first segment really is. First cut would be to only dump >>>>>>> the first segment, so correct code is: >>>>>>> ``` >>>>>>> uint32_t seg_len; >>>>>>> char *buf = (char *)odp_packet_offset(packets[i], 0, &seg_len, NULL); >>>>>>> ``` >>>>>>> And use `seg_len` rather than `pkt_len` in this routine. >>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote: >>>>>>>> Does pcapng not supply a `.h` file for these "magic numbers" and >>>>>>>> associated structs? >>>>>>>>> Ilias Apalodimas(apalos) wrote: >>>>>>>>> Will fix. This will also remove the requirement of manually deleting >>>>>>>>> the fifos >>>>>>>>>> muvarov wrote >>>>>>>>>> odp_global_data_s->main_pid needs to be here. https://github.com/Linaro/odp/pull/435#discussion_r165572134 updated_at 2018-02-02 07:15:34